home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / f1 / tutorc.arj / TEOCPP.DAT < prev    next >
Encoding:
Text File  |  1993-07-08  |  297.5 KB  |  9,601 lines

  1. ;
  2. ; TEORIA DEL LENGUAJE C++
  3. ;
  4.  
  5. ; LECCION 1
  6. begin
  7. beginv
  8. borde 2
  9. color 1 7
  10. centrar_coordenadas
  11. cabecera " INTRODUCCION AL CURSO DE C++ "
  12. "~                                                                      ~"
  13. "~  El objetivo de este curso es enseñar el lenguaje C++, o dicho de    ~"
  14. "~  otro modo, enseñar a programar en lenguaje C++.                     ~"
  15. "~                                                                      ~"
  16. endv
  17. beginv
  18. centrar_coordenadas
  19. cabecera " INDICE DE ESTA LECCION "
  20. ""
  21. "En esta lección se va a estudiar los siguientes puntos:"
  22. ""
  23. "- Idea general y origen del lenguaje C++."
  24. ""
  25. "- Programación orientada a objetos (OOP)."
  26. ""
  27. "- Características principales de la OOP:"
  28. ""
  29. "   · Encapsulación."
  30. ""
  31. "   · Herencia."
  32. ""
  33. "   · Polimorfismo"
  34. ""
  35. "- Forma de implementar las clases en C++."
  36. ""
  37. endv
  38. borrar_pantalla
  39. beginv
  40. coordenadas 2 4
  41. color 15 2
  42. cabecera " IDEA GENERAL DEL LENGUAJE C++ "
  43. "Aunque C es uno de los mejores lenguajes de programación de propó-"
  44. "sito general, a medida que un sistema software se va haciendo más"
  45. "grande se va acentuando más algunas deficiencias del C, como es la"
  46. "casi ilimitada libertad que tiene el programador sobre las rutinas"
  47. "que se implementan. El C++ soluciona este problema facilitando la"
  48. "creación de unidades funcionales de caja negra que tienen acceso"
  49. "estrictamente controlado; a estas unidades se les llama objetos, por"
  50. "este motivo se dice que el ~C++ es un lenguaje orientado a objetos~."
  51. endv
  52. beginv
  53. coordenadas 2 16
  54. cabecera " ORIGEN "
  55. "El C++ se llamó originalmente ~C con clases~ y fue desarrollado por Bjarne"
  56. "Stroustrup de los laboratorios Bell en Murray Hill, New Jersey, en 1983."
  57. "El C++ se puede considerar como una ~ampliación del C estándar~, por lo que"
  58. "la mayor parte de lo que conocemos del C es aplicable al C++."
  59. endv
  60. beginv
  61. centrar_coordenadas_y 2
  62. color 15 1
  63. "Es necesario dejar claro en este momento que este tutor enseña el"
  64. "lenguaje C++, no la programación orientada a objetos (OOP), aunque"
  65. "la mayoría de los programas de C++ implementados en este tutor son"
  66. "programas orientados a objetos. Como el lenguaje C se estudió en"
  67. "el tutor de C, ~en este tutor estudiaremos todas las características~"
  68. "~específicas del C++~, es decir, aquellas características que posee"
  69. "el C++ y no las posee el C. Profundizaremos bastante en todas ellas"
  70. "de manera que no dejemos nada sin comentar. Como ya se dijo en el"
  71. "tutor de C, leyendo simplemente este tutor y libros de C++ no se"
  72. "aprende este lenguaje, sino que ~es imprescindible e ineludible pro-~"
  73. "~gramar en C++~, y cuanto más se programe, mejor se captarán los con-"
  74. "ceptos y más rápido se aprenderá."
  75. endv
  76. beginv
  77. cabecera " PROGRAMACION ORIENTADA A OBJETOS "
  78. centrar_coordenadas_y 2
  79. color 15 4
  80. "Aunque acabamos de decir que el objetivo de este tutor es enseñar el"
  81. "lenguaje C++ y no la programación orientada a objetos, lo cual podría"
  82. "ocupar otro tutor completo ya que es otra forma de programar y de pen-"
  83. "sar en términos programáticos, sí es pertinente mostrar cuáles son las"
  84. "principales características de esta nueva metodología de la programa-"
  85. "ción. Estos rasgos principales los podemos resumir en tres: ~encapsula-~"
  86. "~ción, herencia y polimorfismo.~"
  87. endv
  88. borrar_pantalla
  89. beginv
  90. cabecera " ENCAPSULACION "
  91. centrar_coordenadas_x 2
  92. color 15 5
  93. "~La programación orientada a objetos (OOP) está basada en la manipulación~"
  94. "~de objetos. Un objeto es un concepto que alberga datos y funciones que~"
  95. "~operan con esos datos~. Una vez que se ha implementado un objeto, lo único"
  96. "que necesita saber un programador es la interface con la cual comunicarse"
  97. "con él."
  98. endv
  99. beginv
  100. centrar_coordenadas_x 5
  101. "Para entender mejor la idea de objeto, supongamos que un reloj digital es"
  102. "un objeto. Los datos serían: la hora, la fecha, etc. La interface estaría"
  103. "formada por las funciones que manipulan esos datos: mostrar la hora, mos-"
  104. "trar la fecha, cambiar la hora, cambiar la fecha, etc. Observad que el"
  105. "usuario no necesita saber cómo están implementadas tales funciones para"
  106. "manipular los datos; incluso se podría cambiar la implementación de estas"
  107. "funciones y la interface seguiría siendo la misma."
  108. endv
  109. beginv
  110. centrar_coordenadas_x 10
  111. "Un ejemplo de objeto en programación podría ser una pila. La interface"
  112. "estaría formada por dos funciones: apilar y desapilar. Al usuario del"
  113. "objeto no le importa cuáles son los datos del objeto ni cómo están im-"
  114. "plementadas estas dos funciones. El programador del objeto podría dise-"
  115. "ñar la pila como un array estático y cambiar posteriormente la imple-"
  116. "mentación para que la pila esté diseñada como una lista dinámica enla-"
  117. "zada. Al usuario de la pila no le afectaría en nada el cambio de diseño"
  118. "en la pila, puesto que la interface seguiría siendo la misma, esto es,"
  119. "formada por las funciones: apilar y desapilar."
  120. endv
  121. beginv
  122. centrar_coordenadas_x 15
  123. ""
  124. "  ~Los objetos también reciben el nombre de tipo~  "
  125. "  ~abstracto de datos (TAD, DAT en inglés).     ~"
  126. ""
  127. "  ~Y la encapsulación recibe también el nombre  ~"
  128. "  ~de abstracción de datos.                     ~"
  129. ""
  130. endv
  131. borrar_pantalla
  132. beginv
  133. cabecera " HERENCIA "
  134. centrar_coordenadas
  135. color 15 6
  136. "Una de las características fundamentales en los lenguajes orientados"
  137. "a objetos es la herencia. Gracias a esto ~un determinado objeto puede~"
  138. "~"heredar" propiedades de otros objetos~. Estos vínculos nos permiten,"
  139. "en primer lugar, evitar informaciones duplicadas. Pero su importancia"
  140. "va mucho más allá, ya que el concepto de herencia implica una clasi-"
  141. "ficación y una interdependencia entre los objetos. Veamoslo con un"
  142. "ejemplo."
  143. endv
  144. beginv
  145. centrar_coordenadas_x 2
  146. no_sombra
  147. "Supongamos que definimos el objeto animal. Este objeto abstracto tiene"
  148. "una serie de características: es un ser vivo, necesita alimentarse, se"
  149. "reproduce, etc."
  150. ""
  151. pulsación
  152. "Acto seguido definimos el objeto mamífero indicándole que es un animal."
  153. "Este objeto posee todas las características de los animales y además le"
  154. "añade nuevas características: es vertebrado, tiene mamas, etc."
  155. ""
  156. pulsación
  157. "A continuación definimos el objeto persona indicándole que es un mamí-"
  158. "fero por lo que herederá todas las características de los mamíferos y"
  159. "de los animales. Además les añadimos otras que son propias a las perso-"
  160. "nas: habla, es racional, etc."
  161. ""
  162. pulsación
  163. "Por último, definimos el objeto alumno indicándole que es una persona."
  164. "El objeto alumno tendrá todas las características de persona y tendrá"
  165. "también las suyas propias: matrícula, asignaturas que tiene, etc."
  166. ""
  167. pulsación
  168. "Finalmente, definimos Antonio como una instanciación del objeto alumno,"
  169. "es decir, concretamos el objeto abstracto alumno sobre un elemento real,"
  170. "Antonio; no necesitamos definir nada. El lenguaje ya "sabe" que Antonio"
  171. "es un ser vivo, es vertebrado, etc."
  172. endv
  173. borrar_pantalla
  174. beginv
  175. cabecera " POLIMORFISMO "
  176. centrar_coordenadas
  177. color 14 4
  178. "Vamos a explicar este concepto a través de dos ejemplos."
  179. ""
  180. pulsación
  181. "Imaginemos que tenemos dos pilas, una almacena números enteros y la otra"
  182. "almacena números en coma flotante. Las dos funciones básicas que podemos"
  183. "realizar con una pila son meter y sacar. Como tenemos dos pilas, podría-"
  184. "mos implementar cuatro funciones diferentes con cuatro nombres diferentes:"
  185. "apilaint, desapilaint, apilafloat y desapilafloat. Aunque esto funcione,"
  186. "estamos complicando el programa a nivel conceptual. Utilizando la idea de"
  187. "polimorfismo podemos simplificar conceptualmente el programa implementando"
  188. "cuatro funciones con dos nombres diferentes: apila y desapila. Cuando in-"
  189. "voquemos, por ejemplo, a la función apila, el compilador deberá determinar"
  190. "si llamamos a la función apila de la pila de números enteros o a la función"
  191. "apila de la pila de números en coma flotante. Las funciones apila y desapila"
  192. "se dice que están sobrecargadas."
  193. ""
  194. pulsación
  195. "Los operadores también se pueden sobrecargar en C++. De hecho ya están so-"
  196. "brecargados en casi todos los lenguajes de programación. Por ejemplo, el"
  197. "operador + lo utilizamos en C y C++ para sumar operandos que pueden ser del"
  198. "tipo carácter, entero, coma flotante, etc."
  199. endv
  200. beginv
  201. centrar_coordenadas_y 1
  202. "Veamos otro ejemplo interasente de polimorfismo que hace uso de la herencia."
  203. ""
  204. pulsación
  205. "Supongamos que tenemos definido el objeto punto con la función dibujar, la"
  206. "cual pinta un punto. A continuación definimos el objeto línea que hereda las"
  207. "características del objeto punto. En el objeto lína, utilizando la idea de"
  208. "polimorfismo, volvemos a definir la función dibujar, pero en este caso esta"
  209. "función traza una línea; la función dibujar del objeto línea puede utilizar,"
  210. "si lo desea, la función dibujar, heredada del objeto punto, para dibujar ca-"
  211. "da uno de los puntos de los que está constituida la línea."
  212. endv
  213. borrar_pantalla
  214. beginv
  215. color 14 1
  216. cabecera " FORMA DE IMPLEMENTAR LAS CLASES "
  217. centrar_coordenadas_x 2
  218. "Para terminar con esta introducción al lenguaje C++ vamos a hacer una"
  219. "recomendación. Todos los programas ejemplos de esta lección están en"
  220. "un sólo fichero. La mayoría de los ejemplos están constituidos por la"
  221. "definición de un tipo abstracto de datos (llamados clase en C++ así"
  222. "como a la instanciación de una clase se le llama objeto) y la función"
  223. "main para probar la clase definida. Los programas ejemplos se han rea-"
  224. "lizado en un sólo fichero para facilitar su exposición y explicación"
  225. "en el tutor. No obstante, en la práctica es recomendable dividir el"
  226. "diseño de una clase en dos ficheros: un fichero sería de cabecera (con"
  227. "extensión .H) y en él estarían todas las declaraciones de la clase, y"
  228. "el otro fichero sería de código ejecutable (con extensión .CPP) y en"
  229. "él estarían todas las definiciones relativas a la clase declarada. Al"
  230. "principio del fichero que tiene las definiciones hacemos un #include"
  231. "del fichero que contiene las declaraciones."
  232. endv
  233. beginv
  234. centrar_coordenadas_x 9
  235. "Cuando queramos utilizar esa clase en un programa de C++ tenemos dos"
  236. "posibilidades:"
  237. ""
  238. "1) Si el programa no lo hacemos como proyecto, simplemente hacemos"
  239. "un #include del fichero que contiene las definiciones de la clase al"
  240. "principio del fichero del programa."
  241. ""
  242. "2) Si el programa lo hacemos como proyecto, añadimos a la lista de"
  243. "ficheros del proyecto, el fichero de las definiciones de la clase,"
  244. "bien con extensión .CPP o bien con extensión .OBJ. Además hay que"
  245. "tener en cuenta que debemos hacer un #include del fichero con las"
  246. "declaraciones de la clase, en cada fichero del proyecto que utilice"
  247. "dicha clase."
  248. endv
  249. end lección 1
  250.  
  251. ; LECCION 2
  252. begin
  253. beginv
  254. borde 2
  255. color 1 7
  256. centrar_coordenadas
  257. cabecera " C++ COMO UNA MEJORA DEL C "
  258. "~                                                             ~"
  259. "~  Esta lección explica las nuevas características de C++ no  ~"
  260. "~  orientadas a objetos. Se trata de un importante número de  ~"
  261. "~  pequeñas adiciones que hace el C++ sobre el C.             ~"
  262. "~                                                             ~"
  263. endv
  264. beginv
  265. centrar_coordenadas
  266. cabecera " INDICE DE ESTA LECCION "
  267. ""
  268. "En esta lección se va a estudiar los siguientes puntos:"
  269. ""
  270. "- Nuevo estilo de comentario (con ~\\~)."
  271. "- Declaraciones (en cualquier sitio)."
  272. "- Los nombres de struct y enum son tipos."
  273. "- Operador de resolución de ámbito (~::~)."
  274. "- Declaraciones por referencia (con el operador ~&~)."
  275. "- Uniones anónimas (uniones sin nombre)."
  276. "- Conversión de tipo explícita (notación funcional de los moldes)."
  277. "- Funciones en línea (~inline~)."
  278. "- Argumentos por defecto."
  279. "- Funciones sobrecargadas (antiguamente se especificaba con ~overload~).  "
  280. "- Operadores de almacenamiento libre (~new~ y ~delete~)."
  281. "- Entrada/Salida estándar (con los flujos ~cout~ y ~cin~, y con los"
  282. "  operadores sobrecargados ~<<~ y ~>>~, que se encuentran declarados"
  283. "  en los ficheros de cabecera ~stream.h~ y ~iostream.h~)."
  284. ""
  285. endv
  286. borrar_pantalla
  287. beginv
  288. cabecera " COMENTARIOS "
  289. centrar_coordenadas
  290. color 14 2
  291. ""
  292. "  C++ introduce un nuevo estilo de comentario con el símbolo ~//~.  "
  293. ""
  294. "  Este símbolo indica comentario hasta final de línea."
  295. ""
  296. "  Ejemplos:"
  297. ""
  298. "    int x; // a es una variable de tipo int"
  299. "    int y; /* y es una variable de tipo int */"
  300. ""
  301. endv
  302. beginv
  303. cabecera " DECLARACIONES "
  304. centrar_coordenadas_x 2
  305. color 15 2
  306. "En C, las declaraciones locales han de ir inmediatamente después de las"
  307. "llaves de comienzo de bloque. En C++ se puede declarar una variable en"
  308. "cualquier sitio, existiendo desde el punto de declaración hasta el final"
  309. "del bloque en la que se ha declarado."
  310. ""
  311. "Ejemplo:"
  312. "  {"
  313. "    int x;"
  314. "    x = 10;"
  315. "    int y; // esta línea no es correcta en C, pero sí en C++"
  316. "    y = 20;"
  317. "  }"
  318. endv
  319. beginv
  320. centrar_coordenadas_x 3
  321. color 4 2
  322. no_sombra
  323. "Una declaración muy frecuente en C++ es la siguiente:"
  324. ""
  325. "  for (int i = iinic; i <= ifin; i++)"
  326. "    {"
  327. "      sentencias"
  328. "    }"
  329. ""
  330. "La variable i sólo tiene existencia en el bloque en"
  331. "el que está declarada."
  332. ""
  333. "Ejemplo:"
  334. ""
  335. "  for (register int i = 0; i < IMAX; i++)"
  336. "    {"
  337. "      int t = v[i-1];"
  338. "      v[i-1] = v[i];"
  339. "      v[i] = t;"
  340. "    }"
  341. endv
  342. beginv
  343. centrar_coordenadas_x 4
  344. color 1 2
  345. "En C++, los nombres de enum y de struct son tipos. Esto nos permite"
  346. "hacer los siguiente:"
  347. ""
  348. "  enum ecolores { rojo, verde, azul };"
  349. "  struct scolores { ecolores color; char nombre_color[20]; };"
  350. "  scolores color; // color es de tipo scolores"
  351. ""
  352. "En C, las anteriores sentencias habría que hacerlas del siguiente modo: "
  353. ""
  354. "  enum ecolores { rojo, verde, azul };"
  355. "  struct scolores { enum ecolores color; char nombre_color[20]; };"
  356. "  struct scolores color; // color es de tipo struct scolores"
  357. endv
  358. beginv
  359. cabecera " OPERADOR DE RESOLUCION DE AMBITO (::) "
  360. centrar_coordenadas_x 2
  361. color 15 3
  362. ""
  363. "  C es un lenguaje estructurado en bloque. C++ hereda los"
  364. "  mismos conceptos de bloque y ámbito."
  365. ""
  366. "  El operador ~::~ se usa del siguiente modo:"
  367. ""
  368. "   ~::variable~"
  369. ""
  370. "  y tiene el significado de permitir el acceso a variable,  "
  371. "  que debe estar declarada externamente."
  372. ""
  373. endv
  374. beginv
  375. centrar_coordenadas_x 3
  376. color 14 3
  377. ""
  378. "  // Ejemplo del operador ::"
  379. "  // Este programa imprime «3 1 2 1»"
  380. ""
  381. "  #include <stdio.h>"
  382. ""
  383. "  int i = 1; // i externa"
  384. ""
  385. "  void main (void)"
  386. "  {"
  387. "    int i = 2; // i local a función main()"
  388. "    {"
  389. "      int i = 3; // i local al bloque en la que está declarada  "
  390. "      printf ("%d %d ", i, ::i); // imprime «3 1»"
  391. "    }"
  392. "    printf ("%d %d ", i, ::i); // imprime «2 1»"
  393. "  }"
  394. ""
  395. endv
  396. beginv
  397. cabecera " DECLARACIONES POR REFERENCIA Y LLAMADAS POR REFERENCIA "
  398. color 15 1
  399. centrar_coordenadas_x 2
  400. no_sombra
  401. "El operador ~&~ tiene en C++ un significado adicional a los que ya"
  402. "tiene en C: declarar una variable o un parámetro de una función"
  403. "como referencia de otra variable."
  404. ""
  405. "La forma general de declara una variable como referencia de otra es:"
  406. "  ~tipo & identificador = objeto~"
  407. ""
  408. "Ejemplo:"
  409. ""
  410. "  #include <stdio.h>"
  411. "  void main (void)"
  412. "  {"
  413. "    int i;"
  414. "    int& i1 = i;"
  415. "    int& i2 = i1;"
  416. "    int& i3 = i2;"
  417. "    i = 1;"
  418. "    printf ("%d ", i1); // imprime «1»"
  419. "    i2 = 2;"
  420. "    printf ("%d ", i3); // imprime «2»"
  421. "  }"
  422. endv
  423. beginv
  424. centrar_coordenadas_x 3
  425. color 14 1
  426. "Otros ejemplos:"
  427. ""
  428. "  double a[10];"
  429. "  double& ultimo = a[9]; // ultimo es un alias para a[9]"
  430. "  char& nueva_linea = '\n';"
  431. ""
  432. "El nombre ultimo es una alternativa para el elemento del array a[9]."
  433. ""
  434. "Estos nombres, una vez que son inicializados, no pueden ser cambiados."
  435. ""
  436. "También es posible inicializar una referencia a un literal, lo cual"
  437. "crea una referencia a una localización desconocida donde se almacena"
  438. "el literal."
  439. endv
  440. beginv
  441. centrar_coordenadas_x 4
  442. color 7 1
  443. "El uso principal del operador & con el significado que acabamos de describir"
  444. "se da en los argumentos pasados por referencia. Observar estas dos versiones"
  445. "de la misma función:"
  446. ""
  447. "  // estilo C                              // estilo C++"
  448. "  void intercambiar (int *px, int *py)     void intercambiar (int&x, int&y)"
  449. "  {                                        {"
  450. "    int aux = *px;                           int aux = x;"
  451. "    *px = *py;                               x = y;"
  452. "    *py = aux;                               y = x;"
  453. "  }                                        }"
  454. ""
  455. "Es obvio que la segunda versión de la función intercambiar() es mucho más"
  456. "clara que la primera."
  457. endv
  458. beginv
  459. centrar_coordenadas_x 5
  460. color 12 1
  461. "También los valores devueltos por las funciones pueden ser por refe-"
  462. "rencia. Como es de suponer, el valor devuelto ha de ser una referencia"
  463. "a una variable no local a la función que devuelve el valor. Ejemplo:"
  464. ""
  465. "  #include <stdio.h>"
  466. ""
  467. "  int& f (int &x)"
  468. "  {"
  469. "    return x;"
  470. "  }"
  471. ""
  472. "  void main (void)"
  473. "  {"
  474. "    int y;"
  475. "    f(y) = 20; // en realidad el 20 se asigna a y"
  476. "    printf ("%d", y); // imprime «20»"
  477. "  }"
  478. endv
  479. beginv
  480. centrar_coordenadas_x 6
  481. color 10 1
  482. "Estas dos funciones son incorrectas:"
  483. ""
  484. "  int& f1 (void)"
  485. "  {"
  486. "    int x = 10;"
  487. "    return x;"
  488. "  }"
  489. ""
  490. "  int& f2 (void)"
  491. "  {"
  492. "    return 10;"
  493. "  }"
  494. ""
  495. "El compilador debe informar de error"
  496. "de compilación en ambos return."
  497. endv
  498. beginv
  499. cabecera " UNIONES ANONIMAS "
  500. centrar_coordenadas
  501. color 14 5
  502. ""
  503. "  Las uniones anónimas son las uniones que no  "
  504. "  tienen nombre. El C no dispone de ellas."
  505. ""
  506. "  Ejemplo:"
  507. ""
  508. "   // C++                // C"
  509. "   union                 union"
  510. "     {                     {"
  511. "       int d;                 int d;"
  512. "       float f;               float f;"
  513. "     };                    } u;"
  514. "   f = 1.1;              u.f = 1.1;"
  515. "   printf ("%d", d);     printf ("%d", u.d);"
  516. ""
  517. endv
  518. beginv
  519. cabecera " CONVERSION DE TIPO EXPLICITA "
  520. centrar_coordenadas
  521. color 15 4
  522. "En C++, el nombre de un tipo puede ser usado como una función para realizar"
  523. "una conversión de tipo. Esto supone una alternativa a los moldes."
  524. ""
  525. "Ejemplo:"
  526. ""
  527. " #include <stdio.h>"
  528. ""
  529. " void main (void)"
  530. " {"
  531. "   int i = 10;"
  532. "   float f1 = i;         // conversión de tipo implícita"
  533. "   float f2 = (float) i; // conversión de tipo explícita: notación molde"
  534. "   float f3 = float (i); // conversión de tipo explícita: notación funcional"
  535. ""
  536. "   printf ("%g %g %g", f1, f2, f3); // imprime «10 10 10»"
  537. " }"
  538. endv
  539. beginv
  540. centrar_coordenadas
  541. color 14 4
  542. "Otro ejemplo de conversión explí-"
  543. "cita mediante notación funcional:"
  544. ""
  545. "  struct st { int d; float f; };"
  546. "  typedef st *pst;"
  547. "  char *str = "abcdef";"
  548. "  pst p = pst (str);"
  549. endv
  550. beginv
  551. cabecera " FUNCIONES INLINE "
  552. centrar_coordenadas_x 3
  553. color 15 6
  554. "En el curso de C vimos que las macros pueden dar problemas como éste:"
  555. ""
  556. "Dado"
  557. "  #define CUAD(x) x*x"
  558. "la sentencia"
  559. "  CUAD(a+b)"
  560. "expande a:"
  561. "  a+b*a+b"
  562. "que no es evidentemente la expresión esperada."
  563. ""
  564. "El problema puede ser evitado parentizando la definición de la macro."
  565. "Sin embargo, la solución no protege contra tipos impropios."
  566. endv
  567. beginv
  568. centrar_coordenadas_x 4
  569. color 14 6
  570. "El C++ ofrece una alternativa elegante"
  571. "y eficiente usando funciones inline:"
  572. ""
  573. "  inline int cuad (int x)"
  574. "  {"
  575. "    return x*x;"
  576. "  }"
  577. ""
  578. "La palabra clave ~inline~ le dice al com-"
  579. "pilador que la función sea compilada"
  580. "como una macro, es decir, el especi-"
  581. "ficador inline fuerza al compilador de"
  582. "C++ a sustituir el cuerpo de código de"
  583. "cuad() en el lugar en que esta función"
  584. "es invocada."
  585. endv
  586. beginv
  587. centrar_coordenadas_x 5
  588. color 11 6
  589. "Aunque el uso de inline incrementa la velocidad"
  590. "de ejecución porque se elimina la llamada a la"
  591. "función, produce un incremento del tamaño del"
  592. "código, especialmente si la función inline con-"
  593. "tiene muchas líneas de código y es incovada mu-"
  594. "chas veces en el programa."
  595. ""
  596. "Otro ejemplo de función inline:"
  597. ""
  598. "  inline void imprimir (int a, int b)"
  599. "  {"
  600. "    printf ("\n%d", a);"
  601. "    printf ("\n%d", b);"
  602. "  }"
  603. endv
  604. beginv
  605. cabecera " ARGUMENTOS POR DEFECTO "
  606. centrar_coordenadas_x 4
  607. color 1 7
  608. "Uno o más argumentos en una función de C++ pueden ser especificado"
  609. "teniendo valores por defecto."
  610. ""
  611. "Ejemplo:"
  612. ""
  613. "  #include <stdio.h>"
  614. ""
  615. "  int mult (int x, int y = 1)"
  616. "  {"
  617. "    return (x * y);"
  618. "  }"
  619. ""
  620. "  void main (void)"
  621. "  {"
  622. "    printf ("%d %d", mult (5, 6), mult (7)); // imprime «30 7»"
  623. "  }"
  624. endv
  625. beginv
  626. centrar_coordenadas_x 5
  627. color 9 7
  628. "Sólo los parámetros finales de una función pueden tener"
  629. "valores por defecto."
  630. ""
  631. "Ejemplo:"
  632. ""
  633. "  void f1 (int i, int j = 2);                // legal"
  634. "  void f2 (int i = 3, int j);                // ilegal"
  635. "  void f3 (int i, int j = 4, int k = 5);     // legal"
  636. "  void f4 (int i = 6, int j = 7, int k = 8); // legal"
  637. "  void f5 (int i, int j = 9, int k);         // ilegal"
  638. endv
  639. beginv
  640. cabecera " FUNCIONES SOBRECARGADAS "
  641. centrar_coordenadas_x 5
  642. color 15 2
  643. ""
  644. "  El término sobrecarga se refiere al uso del mismo nombre para varios"
  645. "  significados de un operador o una función. El significado seleccionado  "
  646. "  depende de los tipos de los argumentos usados por el operador o la"
  647. "  función."
  648. ""
  649. "  El primer estándar C++ introducía la palabra clave ~overload~ para in-"
  650. "  dicar que un nombre particular será sobrecargado. En el nuevo estándar"
  651. "  de C++ se considera obsoleto el uso de esta instrucción."
  652. ""
  653. "  En este momento restringiremos nuestra discusión a la sobrecarga de"
  654. "  funciones y dejaremos la sobrecarga de operadores para lecciones pos-"
  655. "  teriores."
  656. ""
  657. endv
  658. beginv
  659. centrar_coordenadas_x 2
  660. color 0 2
  661. no_sombra
  662. "  // Ejemplo de sobrecarga de funciones"
  663. ""
  664. "  overload media_array; // opcional en el nuevo estándar de C++"
  665. "  double media_array (double a[], int tam);"
  666. "  double media_array (int a[], int tam);"
  667. ""
  668. "  double media_array (int a[], int tam)"
  669. "  {"
  670. "    int sum = 0;"
  671. "    for (int i = 0; i < tam; ++i)"
  672. "      sum += a[i]; // ejecuta aritmética de enteros"
  673. "    return ((double) sum / tam);"
  674. "  }"
  675. ""
  676. "  double media_array (double a[], int tam)"
  677. "  {"
  678. "    double sum = 0.0;"
  679. "    for (int i = 0; i < tam; ++i)"
  680. "      sum += a[i]; // ejecuta aritmética de double"
  681. "    return (sum / tam);"
  682. "  }"
  683. endv
  684. beginv
  685. centrar_coordenadas
  686. color 4 2
  687. "El compilador elige automáticamente la función"
  688. "que coincide con los tipos de los argumentos."
  689. ""
  690. "Atención: No se puede sobrecargar dos funciones"
  691. "que tengan iguales tipos de argumentos y dis-"
  692. "tintos tipos de valores devueltos. Es ilegal,"
  693. "por lo tanto, lo siguiente:"
  694. ""
  695. "  overload f;"
  696. "  int f (void);"
  697. "  double f (void);"
  698. endv
  699. beginv
  700. cabecera " OPERADORES DE ALMACENAMIENTO LIBRE (new y delete) "
  701. centrar_coordenadas_x 2
  702. color 14 3
  703. ""
  704. "  Los operadores unarios ~new~ y ~delete~ están disponibles para manipular  "
  705. "  el almacenamiento libre. Estos operadores reemplazan a las funciones"
  706. "  de la biblioteca estándar malloc(), calloc() y free(). En C++ se re-"
  707. "  comienda usar estos operadores a tales funciones. El almacenamento"
  708. "  libre se refiere al sistema por el cual el programador gestiona di-"
  709. "  rectamente el tiempo de vida de los objetos. El programador crea el"
  710. "  objeto usando new y lo destruye usando delete. Esto es importante"
  711. "  para estructuras de datos dinámicas como las listas y los árboles."
  712. ""
  713. endv
  714. beginv
  715. centrar_coordenadas_x 3
  716. color 15 3
  717. "El operador new se puede usar de las siguientes formas:"
  718. ""
  719. "  new nombre_tipo"
  720. "  new nombre_tipo inicializador"
  721. "  new (nombre_tipo)"
  722. ""
  723. "En cada caso se producen dos efectos. Primero, es asignada la cantidad"
  724. "apropiada de almacenamiento para contener al nuevo tipo. Segundo, la"
  725. "dirección base del objeto es devuelta como el valor de la expresión"
  726. "new. La expresión es de tipo void * y puede ser asignada a cualquier"
  727. "tipo puntero. Si no hay suficiente memoria, este operador devuelve nu-"
  728. "lo. El uso del operador con inicializador se aplica a las clases por"
  729. "lo que se explica en posteriores lecciones. Después del tipo puede ir"
  730. "entre corchetes el número de elementos de ese tipo a reservar."
  731. ""
  732. "Ejemplos:"
  733. "  int *pi;         char *pc;                float *pf; int n = 2;"
  734. "  pi = new int;    pc = new char[10];       pf = new float[n];"
  735. "  *pi = 5;         strcpy (pc, "hola");     pf[0] = 1.1; pf[1] = 2.2;"
  736. endv
  737. beginv
  738. centrar_coordenadas_x 4
  739. color 5 3
  740. "El operador delete destruye un objeto creado por new dejando libre"
  741. "el espacio ocupado por este objeto para poder ser reusado. El opera-"
  742. "dor delete se puede usar de las siguientes formas:"
  743. ""
  744. "  delete expresion"
  745. "  delete [expresion] expresion"
  746. ""
  747. "La primera forma es la más común. La expresión es normalmente una"
  748. "variable puntero usada en una expresión new previa. La segunda forma"
  749. "es utilizada menos frecuentemente y se usa cuando se asignó un array"
  750. "con new. La expresión entre corchetes especifica el número de ele-"
  751. "mentos del array a liberar. Dicho tamaño del vector proporcionado"
  752. "por el usuario es ignorado excepto para algunos tipos definidos por"
  753. "el usuario (referencia: apartado "Vectores de objetos de clases" en"
  754. "lección 4 del tutor de C++). El operador delete no devuelve ningún"
  755. "valor (o también se puede decir que su tipo devuelto es void). El"
  756. "operador delete sólo puede ser aplicado a punteros devueltos por new"
  757. "o a cero; aplicar delete a cero no tiene ningún efecto."
  758. endv
  759. beginv
  760. cabecera " ENTRADA/SALIDA ESTANDAR EN C++ "
  761. centrar_coordenadas_x 2
  762. color 15 5
  763. no_sombra
  764. "La E/S estándar en C++ se va a estudiar en detalle en lecciones pos-"
  765. "teriores. Aquí sólo se va a comentar los conocimientos mínimos para"
  766. "poder utilizarla en los ejemplos."
  767. ""
  768. "En el primer estándar de C++, la utilización de las facilidades de E/S"
  769. "necesitaba la inclusión del fichero de cabecera ~<stream.h>~. En el nuevo"
  770. "estándar es preferible utilizar el fichero de cabecera ~<iostream.h>~ que"
  771. "mejora y añade nuevas características a <stream.h>. Lo que se va a co-"
  772. "mentar en este momento requiere uno de los dos ficheros de cabecera an-"
  773. "teriores; si el compilador que usas no contiene el fichero iostream.h,"
  774. "seguro que tiene el stream.h."
  775. ""
  776. "A partir de este momento, la salida estándar la realizaremos con el"
  777. "identificador ~cout~ y el operador sobrecargado ~<<~, y la entrada estándar"
  778. "la realizaremos con el identificador ~cin~ y el operador sobrecargado ~>>~."
  779. "Para poder utilizar en un programa los identificadores cout, cin y sus"
  780. "correspondientes operadores sobrecargados, tenemos que hacer al princi-"
  781. "pio de esto:"
  782. ""
  783. "  #include <iostream.h> // para los compiladores que no dispongan de"
  784. "                        // este fichero: #include <stream.h>"
  785. endv
  786. beginv
  787. centrar_coordenadas_x 3
  788. color 14 5
  789. no_sombra
  790. ""
  791. "  // Ejemplo de cómo utilizar la E/S de C++"
  792. ""
  793. "  #include <iostream.h>"
  794. ""
  795. "  void main (void)"
  796. "  {"
  797. "    // equivalente a printf ("C++ es un C mejorado.\n");"
  798. "    cout << "C++ es un C mejorado.\n";"
  799. ""
  800. "    // equivalente a printf ("2 + 2 = %d\n", 2 + 2);"
  801. "    cout << "2 + 2 = " << 2 + 2 << '\n';"
  802. ""
  803. "    int n;"
  804. "    cin >> n; // equivalente a scanf ("%d", &n);"
  805. ""
  806. "    float f1, f2;"
  807. "    cin >> f1 >> f2; // equivalente a scanf ("%f%f", &f1, &f2);  "
  808. "  }"
  809. ""
  810. endv
  811. beginv
  812. centrar_coordenadas
  813. color 10 5
  814. "Los identificadores cout y cin son los"
  815. "nombres de los flujos de salida y entrada"
  816. "estándar, respectivamente. Los operadores"
  817. "<< y >> indican la dirección del flujo de"
  818. "información."
  819. endv
  820. end lección 2
  821.  
  822. ; LECCION 3
  823. begin
  824. beginv
  825. borde 2
  826. color 1 7
  827. centrar_coordenadas
  828. cabecera " CLASES "
  829. ""
  830. "  ~ Esta lección describe las facilidades de C++ para definir nuevos tipos ~  "
  831. "  ~ en los cuales el acceso a los datos está restringido a un conjunto es- ~"
  832. "  ~ pecífico de funciones. A estos nuevos tipos se les denomina tipos abs- ~"
  833. "  ~ tractos de datos (TAD en castellano y ADT en inglés).                  ~"
  834. ""
  835. "  ~ Una clase (class) es una extensión de la idea de estructura (struct)   ~"
  836. "  ~ en C. El nombre original dado por Stroustrup a este lenguaje fue "C    ~"
  837. "  ~ con clases".                                                           ~"
  838. ""
  839. "  ~ Una estructura en C está compuesta por un conjunto de datos. Una clase ~"
  840. "  ~ o una estructura en C++ está compuesta de un conjunto de datos junto   ~"
  841. "  ~ con un conjunto de funciones y operadores para manipular esos datos.   ~"
  842. ""
  843. endv
  844. beginv
  845. centrar_coordenadas
  846. cabecera " INDICE DE ESTA LECCION "
  847. ""
  848. "En esta lección se va a estudiar los siguientes puntos:"
  849. ""
  850. "- El tipo compuesto ~struct~."
  851. "- Visibilidad de los miembros de un objeto (~private~ y ~public~)."
  852. "- Tipos compuestos ~struct~ y ~class~."
  853. "- Declaración de funciones miembros."
  854. "- Operador de resolución de ámbito (~::~)."
  855. "- Miembro ~static~."
  856. "- Clases anidadas."
  857. "- Estructuras y uniones (~struct~ y ~union~)."
  858. "- Punteros a miembros (~::*~, ~.*~ y ~->*~)."
  859. "- Precedencia de operadores."
  860. ""
  861. endv
  862. borrar_pantalla
  863. beginv
  864. cabecera " EL TIPO COMPUESTO struct "
  865. centrar_coordenadas_x 2
  866. color 15 1
  867. ""
  868. "  En C++, a los elementos de una estructura  "
  869. "  se les llama ~miembros~. Además, extiende"
  870. "  el concepto de estructura."
  871. ""
  872. "  Para explicar estas mejoras vamos a hacer"
  873. "  dos versiones de un mismo programa: la"
  874. "  primera versión utilizando el concepto de"
  875. "  struct del C y la segunda utilizando el"
  876. "  concepto de struct del C++."
  877. ""
  878. endv
  879. beginvis
  880. no_posicion
  881. cabecera " DOS VERSIONES DE UN MISMO PROGRAMA "
  882. coordenadas_completas 3 3 78 23
  883. color 14 1
  884. borde 2
  885. ""
  886. "~// VERSION 1. UTILIZA CONCEPTO DE STRUCT DEL C~"
  887. ""
  888. "#include <iostream.h> // cout, << sobrecargado; también vale <stream.h>"
  889. ""
  890. "const int longit_max = 1000;"
  891. "enum boolean { false, true };"
  892. ""
  893. "struct pila"
  894. "  {"
  895. "    char s[longit_max]; // no permitido en el ANSI C, sí en el ANSI C++"
  896. "    int cima;"
  897. "  };"
  898. ""
  899. "void inicializar (pila *pil)"
  900. "{"
  901. "  pil->cima = 0;"
  902. "}"
  903. ""
  904. "void meter (char c, pila *pil)"
  905. "{"
  906. "  pil->s[++pil->cima] = c;"
  907. "}"
  908. ""
  909. "char sacar (pila *pil)"
  910. "{"
  911. "  return (pil->s[pil->cima--]);"
  912. "}"
  913. ""
  914. "char elem_cima (pila *pil)"
  915. "{"
  916. "  return (pil->s[pil->cima]);"
  917. "}"
  918. ""
  919. "boolean vacia (pila *pil)"
  920. "{"
  921. "  return boolean (pil->cima == 0);"
  922. "}"
  923. ""
  924. "boolean llena (pila *pil)"
  925. "{"
  926. "  return boolean (pil->cima == longit_max - 1);"
  927. "}"
  928. ""
  929. "void main (void)"
  930. "{"
  931. "  pila p;"
  932. "  char *cad;"
  933. ""
  934. "  inicializar (&p);"
  935. "  cad = "Ejemplo de struct del C.";"
  936. ""
  937. "  for (register int i = 0; cad[i]; i++)"
  938. "    if (! llena (&p))"
  939. "      meter (cad[i], &p);"
  940. ""
  941. "  cout << "Cadena original: " << cad << "\n";"
  942. "  cout << "Cadena invertida: ";"
  943. "  while (! vacia (&p))"
  944. "    cout << sacar (&p);"
  945. "  cout << "\n";"
  946. "}"
  947. ""
  948. ""
  949. "~// VERSION 2. UTILIZA CONCEPTO DE STRUCT DEL C++~"
  950. ""
  951. "#include <iostream.h> // cout, << sobrecargado; también vale <stream.h>"
  952. ""
  953. "const int longit_max = 1000;"
  954. "enum boolean { false, true };"
  955. ""
  956. "struct pila"
  957. "  {"
  958. "    private:"
  959. ""
  960. "      char s[longit_max]; // const no permitida en inicializac. en ANSI C"
  961. "      int cima;"
  962. ""
  963. "    public:"
  964. ""
  965. "      void inicializar (void)"
  966. "      {"
  967. "        cima = 0;"
  968. "      }"
  969. ""
  970. "      void meter (char c)"
  971. "      {"
  972. "        s[++cima] = c;"
  973. "      }"
  974. ""
  975. "      char sacar (void)"
  976. "      {"
  977. "        return (s[cima--]);"
  978. "      }"
  979. ""
  980. "      char elem_cima (void)"
  981. "      {"
  982. "        return (s[cima]);"
  983. "      }"
  984. ""
  985. "      boolean vacia (void)"
  986. "      {"
  987. "        return boolean (cima == 0);"
  988. "      }"
  989. ""
  990. "      boolean llena (void)"
  991. "      {"
  992. "        return boolean (cima == longit_max - 1);"
  993. "      }"
  994. "  };"
  995. ""
  996. ""
  997. "void main (void)"
  998. "{"
  999. "  pila p;"
  1000. "  char *cad;"
  1001. ""
  1002. "  p.inicializar ();"
  1003. "  cad = "Ejemplo de struct del C++.";"
  1004. ""
  1005. "  for (register int i = 0; cad[i]; i++)"
  1006. "    if (! p.llena ())"
  1007. "      p.meter (cad[i]);"
  1008. ""
  1009. "  cout << "Cadena original: " << cad << "\n";"
  1010. "  cout << "Cadena invertida: ";"
  1011. "  while (! p.vacia ())"
  1012. "    cout << p.sacar ();"
  1013. "  cout << "\n";"
  1014. "}"
  1015. ""
  1016. ""
  1017. "~SALIDA DE LOS PROGRAMAS:~"
  1018. ""
  1019. "La salida del primer programa es:"
  1020. ""
  1021. "Cadena original: Ejemplo de struct del C."
  1022. "Cadena invertida: .C led tcurts ed olpmejE"
  1023. ""
  1024. "y la del segundo:"
  1025. ""
  1026. "Cadena original: Ejemplo de struct del C++."
  1027. "Cadena invertida: .++C led tcurts ed olpmejE"
  1028. ""
  1029. "Los dos son iguales excepto en el mensaje que invierten."
  1030. ""
  1031. ""
  1032. "~ANALISIS DE LOS EJEMPLOS:~"
  1033. ""
  1034. "En nuestro primer programa no aparece ningún concepto nuevo y el usuario"
  1035. "debe entenderlo todo. En el segundo programa sí aparecen unos cuantos"
  1036. "conceptos nuevos del C++."
  1037. ""
  1038. "La primera novedad que se aprecia es que hay definida funciones dentro"
  1039. "de la estructura. En C, las estructuras sólo pueden tener datos miembros,"
  1040. "en C++, las estructuras también pueden contener ~funciones miembros~."
  1041. ""
  1042. "Algunos libros se refieren a las funciones miembros como métodos. Las"
  1043. "variables de tipo estructura reciben el nombre de objetos."
  1044. ""
  1045. "Como se aprecia en la función main(), a las funciones de una variable"
  1046. "estructura se accede igual que a los datos de esa estructura, es decir,"
  1047. "con el operador punto (.)."
  1048. ""
  1049. "La segunda novedad que vemos en la estructura del ejemplo son las pala-"
  1050. "bras claves ~private~ y ~public~, las cuales hacen que los miembros de"
  1051. "la estructura sean privados o públicos, respectivamente. A los miembros"
  1052. "privados sólo pueden acceder las funciones miembros. A los miembros"
  1053. "públicos puede acceder cualquier función del programa."
  1054. ""
  1055. "La última novedad que aparece en el programa es la definición implícita"
  1056. "de funciones ~inline~: todas aquellas funciones que se definen (no que"
  1057. "se declaran) dentro de una estructura son inline, aunque no vayan prece-"
  1058. "didas por la palabra clave inline."
  1059. ""
  1060. "Estas tres novedades de las estructuras de C++ con respecto al C se van"
  1061. "a discutir más ampliamente en los apartados siguientes. Intenta entender"
  1062. "el segundo programa antes de pasar a las siguientes ventanas e intenta"
  1063. "apreciar la diferencia que existe con respecto a la primera versión del"
  1064. "mismo programa."
  1065. ""
  1066. endvis
  1067. borrar_pantalla
  1068. beginv
  1069. cabecera " VISIBILIDAD DE LOS MIEMBROS DE UN OBJETO "
  1070. centrar_coordenadas_x 2
  1071. color 15 1
  1072. "Desde el punto de vista de la visibilidad o el acceso a los miembros"
  1073. "de un objeto, los miembros pueden ser ~públicos~, ~privados~ o ~protegidos~."
  1074. endv
  1075. beginv
  1076. centrar_coordenadas_x 6
  1077. color 7 1
  1078. "Los miembros protegidos se estudian en lecciones posteriores."
  1079. endv
  1080. beginv
  1081. centrar_coordenadas_x 9
  1082. color 11 1
  1083. "Los miembros privados son aquéllos que están bajo el ámbito de la"
  1084. "palabra clave private seguida por dos puntos (~private:~). Del mismo"
  1085. "modo, los miembros públicos son aquéllos que están bajo el ámbito"
  1086. "de la palabra clave public seguida por dos puntos (~public:~)."
  1087. endv
  1088. beginv
  1089. centrar_coordenadas_x 15
  1090. color 10 1
  1091. "Los miembros privados sólo pueden ser accedidos por las funciones"
  1092. "miembros."
  1093. "Los miembros públicos constituyen la interface con los elementos"
  1094. "de la clase."
  1095. "Si todos los miembros de una clase, datos y funciones, son privados,"
  1096. "no hay ninguna forma de que el programa se pueda comunicar con los"
  1097. "elementos de ese objeto."
  1098. endv
  1099. beginvis
  1100. no_posicion
  1101. no_multiatributo
  1102. cabecera " EJEMPLO SOBRE EL ACCESO A LOS MIEMBROS DE UNA CLASE "
  1103. coordenadas_completas 3 3 78 23
  1104. color 14 1
  1105. borde 2
  1106. ""
  1107. "void main (void)"
  1108. "{"
  1109. "  struct"
  1110. "    {"
  1111. "      private:"
  1112. "        int x;"
  1113. "        void f1 (void) { x = 10; }"
  1114. "        void f2 (void) { y = 10; }"
  1115. ""
  1116. "      public:"
  1117. "        int y;"
  1118. "        void f3 (void) { x = 20; }"
  1119. "        void f4 (void) { y = 20; }"
  1120. "        void f5 (void) { f1 (); f2 (); f3 (); }"
  1121. "    } s;"
  1122. ""
  1123. "  s.x = 1; // ilegal: error de compilación. Miembro x no accesible."
  1124. "  s.f1 (); // ilegal: error de compilación. Miembro f1() no accesible."
  1125. "  s.f2 (); // ilegal: error de compilación. Miembro f2() no accesible."
  1126. "  s.y = 2; // legal"
  1127. "  s.f3 (); // legal"
  1128. "  s.f4 (); // legal"
  1129. "  s.f5 (); // legal"
  1130. "}"
  1131. ""
  1132. endvis
  1133. borrar_pantalla
  1134. beginv
  1135. cabecera " TIPOS COMPUESTOS struct Y class "
  1136. centrar_coordenadas_x 2
  1137. color 15 1
  1138. "Los tipos struct y class son similares. Sólo hay una diferencia entre ellos:"
  1139. "~los miembros de una estructura son por defecto públicos, y los miembros de~"
  1140. "~una clase son por defecto privados~. Esto supone que las palabras claves pri-"
  1141. "vate y public son opcionales."
  1142. endv
  1143. beginv
  1144. centrar_coordenadas_x 8
  1145. color 7 1
  1146. "En este tutor, por convención, los objetos que sólo contengan"
  1147. "datos se declararán como struct, y aquéllos que contengan datos"
  1148. "y funciones se declararán como class."
  1149. endv
  1150. beginvis
  1151. no_posicion
  1152. cabecera " EJEMPLOS DE TIPOS EQUIVALENTES "
  1153. coordenadas_completas 7 13 73 23
  1154. color 14 1
  1155. borde 2
  1156. ""
  1157. "   ~struct s            ~                 ~struct s            ~"
  1158. "   ~  {                 ~                 ~  {                 ~"
  1159. "   ~    int i;          ~      <===>      ~    public:         ~"
  1160. "   ~    void f (void);  ~                 ~      int i;        ~"
  1161. "   ~  };                ~                 ~      void f (void);~"
  1162. "   ~                    ~                 ~  };                ~"
  1163. ""
  1164. "   ~class c             ~                 ~class c             ~"
  1165. "   ~  {                 ~                 ~  {                 ~"
  1166. "   ~    int i;          ~      <===>      ~    private:        ~"
  1167. "   ~    void f (void);  ~                 ~      int i;        ~"
  1168. "   ~  };                ~                 ~      void f (void);~"
  1169. "   ~                    ~                 ~  };                ~"
  1170. ""
  1171. "   ~struct s            ~                 ~class c             ~"
  1172. "   ~  {                 ~                 ~  {                 ~"
  1173. "   ~    int i;          ~      <===>      ~    public:         ~"
  1174. "   ~    void f (void);  ~                 ~      int i;        ~"
  1175. "   ~  };                ~                 ~      void f (void);~"
  1176. "   ~                    ~                 ~  };                ~"
  1177. ""
  1178. "   ~class c             ~                 ~struct s            ~"
  1179. "   ~  {                 ~                 ~  {                 ~"
  1180. "   ~    public:         ~                 ~    int i;          ~"
  1181. "   ~      int i;        ~      <===>      ~    void f (void);  ~"
  1182. "   ~      void f (void);~                 ~  };                ~"
  1183. "   ~  };                ~                 ~                    ~"
  1184. ""
  1185. "   ~struct s            ~                 ~class c             ~"
  1186. "   ~  {                 ~                 ~  {                 ~"
  1187. "   ~    int i;          ~      <===>      ~    void f (void);  ~"
  1188. "   ~                    ~                 ~                    ~"
  1189. "   ~    private:        ~                 ~    public:         ~"
  1190. "   ~      void f (void);~                 ~      int i;        ~"
  1191. "   ~  }                 ~                 ~  };                ~"
  1192. ""
  1193. endvis
  1194. borrar_pantalla
  1195. beginv
  1196. cabecera " DECLARACION DE FUNCIONES MIEMBROS "
  1197. centrar_coordenadas_x 2
  1198. color 15 1
  1199. "Antes de que se pueda utilizar una clase,"
  1200. "todos sus miembros deben estar definidos."
  1201. endv
  1202. beginv
  1203. cabecera " DOS FORMAS DE DEFINIR UNA FUNCION MIEMBRO "
  1204. centrar_coordenadas_x 6
  1205. color 12 1
  1206. "1) Definir la función miembro dentro de la clase. En este caso, aunque"
  1207. "la definición de la función no vaya precedida por la palabra inline, la"
  1208. "función es inline y será tratada como una macro. Naturalmente, se puede"
  1209. "utilizar la palabra clave inline si se desea, aunque no sea necesario"
  1210. "con las funciones miembros."
  1211. ""
  1212. "2) Declarar la función dentro de la clase, es decir, escribir su proto-"
  1213. "tipo dentro de la clase, y definirla fuera, es decir, en el ámbito ex-"
  1214. "terno. En este caso, el nombre de la función miembro en la definición"
  1215. "debe ir precedido con el nombre de la clase seguido por el operador de"
  1216. "resolución de ámbito (::). El nombre de la clase es necesario porque"
  1217. "puede haber otras clases que utilicen el mismo nombre de función."
  1218. endv
  1219. beginv
  1220. centrar_coordenadas_x 20
  1221. color 13 1
  1222. "Las funciones miembros, al igual, que las demás funciones, también se"
  1223. "pueden sobrecargar y sus argumentos pueden tener valores por defecto."
  1224. endv
  1225. beginvis
  1226. no_posicion
  1227. no_multiatributo
  1228. cabecera " EJEMPLO DE DECLARACION DE FUNCIONES MIEMBROS "
  1229. coordenadas_completas 3 3 78 23
  1230. color 14 1
  1231. borde 2
  1232. ""
  1233. "#include <iostream.h>"
  1234. ""
  1235. "class clase"
  1236. "  {"
  1237. "    private:"
  1238. "      int x;"
  1239. ""
  1240. "    public:"
  1241. "      inline void inicializar (void); // declaración de función inline"
  1242. "      void asignar (int y) { x = y; } // definición de función inline"
  1243. "      int devolver (void);            // declaración de función no inline"
  1244. "  };"
  1245. ""
  1246. "void clase::inicializar (void)"
  1247. "{"
  1248. "  x = 0;"
  1249. "}"
  1250. ""
  1251. "int clase::devolver (void)"
  1252. "{"
  1253. "  return x;"
  1254. "}"
  1255. ""
  1256. "void main (void)"
  1257. "{"
  1258. "  clase c;"
  1259. "  cout << (c.inicializar (), c.devolver ())"
  1260. "       << ' '"
  1261. "       << (c.asignar (100), c.devolver ())"
  1262. "       << '\n'; // imprime: «0 100»"
  1263. "}"
  1264. ""
  1265. endvis
  1266. borrar_pantalla
  1267. beginv
  1268. cabecera " OPERADOR DE RESOLUCION DE AMBITO (::) "
  1269. centrar_coordenadas_x 2
  1270. color 15 1
  1271. ""
  1272. "  En la lección anterior dijimos que podíamos referirnos"
  1273. "  explicítamente a un miembro externo de la siguiente forma:  "
  1274. ""
  1275. "    ~::identificador~"
  1276. ""
  1277. "  Otra forma de utilizar este operador es:"
  1278. ""
  1279. "    ~clase::identificador~"
  1280. ""
  1281. "  lo cual es útil para distinguir explicítamente entre los"
  1282. "  nombres de miembros de clase y otros nombres."
  1283. ""
  1284. "  En las dos expresiones anteriores identificador puede ser"
  1285. "  tanto el nombre de una variable como el nombre de una"
  1286. "  función."
  1287. ""
  1288. endv
  1289. beginv
  1290. centrar_coordenadas_x 21
  1291. color 7 1
  1292. no_sombra
  1293. "El operador unario ~::~ tiene la misma prioridad que los operadores "
  1294. "monarios ~()~, ~[]~, ~->~ y ~.~, esto es, tiene la prioriodad más alta."
  1295. endv
  1296. beginvis
  1297. no_posicion
  1298. no_multiatributo
  1299. cabecera " EJEMPLO DEL OPERADOR DE RESOLUCION DE AMBITO "
  1300. coordenadas_completas 3 3 78 23
  1301. color 14 1
  1302. borde 2
  1303. ""
  1304. "#include <iostream.h>"
  1305. ""
  1306. "int x;"
  1307. ""
  1308. "class clase"
  1309. "  {"
  1310. "    private:"
  1311. "      int x;"
  1312. ""
  1313. "    public:"
  1314. "      void asigx (void) { x = 2; }"
  1315. "      int devexpr (void) { return (x + clase::x + ::x); }"
  1316. "  };"
  1317. ""
  1318. "void main (void)"
  1319. "{"
  1320. "  clase c;"
  1321. ""
  1322. "  x = 1;"
  1323. "  c.asigx ();"
  1324. ""
  1325. "  cout << c.devexpr () << " " << x + ::x; // imprime «5 2»"
  1326. "}"
  1327. ""
  1328. endvis
  1329. borrar_pantalla
  1330. beginv
  1331. cabecera " MIEMBRO static "
  1332. centrar_coordenadas_x 2
  1333. color 15 1
  1334. ""
  1335. "  Los datos miembros pueden ser declarados con el modificador"
  1336. "  de clase de almacenamiento static. No pueden ser declarados"
  1337. "  auto, register o extern. ~Un dato miembro que es declarado~"
  1338. "  ~static es compartido por todas las variables de esa clase~"
  1339. "  ~y es almacenado en un lugar únicamente.~ A causa de esto, se"
  1340. "  accede a este miembro, desde fuera de la clase, en la forma"
  1341. "  nombre_de_clase::identificador si tiene visibilidad pública.  "
  1342. ""
  1343. endv
  1344. beginvis
  1345. no_multiatributo
  1346. cabecera " EJEMPLO DE MIEMBRO static "
  1347. coordenadas_completas 3 3 78 23
  1348. color 14 1
  1349. borde 2
  1350. ""
  1351. "#include <iostream.h>"
  1352. ""
  1353. "struct estructura"
  1354. "  {"
  1355. "    int x;"
  1356. "    static int y;"
  1357. "  };"
  1358. ""
  1359. "int estructura::y = 0;"
  1360. ""
  1361. "void main (void)"
  1362. "{"
  1363. "  estructura c1, c2, c3;"
  1364. ""
  1365. "  estructura::y++;"
  1366. ""
  1367. "  c1.y++;"
  1368. "  c2.y++;"
  1369. "  c3.y++;"
  1370. ""
  1371. "  c1.x = c2.x = c3.x = 0;"
  1372. ""
  1373. "  c1.x++;"
  1374. "  c2.x++;"
  1375. "  c3.x++;"
  1376. ""
  1377. "  cout << estructura::y << c1.y << c2.y << c3.y; // imprime «4444»"
  1378. "  cout << c1.x << c2.x << c3.x; // imprime «111»"
  1379. "}"
  1380. ""
  1381. endvis
  1382. borrar_pantalla
  1383. beginv
  1384. cabecera " CLASES ANIDADADAS "
  1385. centrar_coordenadas_x 2
  1386. color 15 1
  1387. "Las clases se pueden anidar. ~La clase interna no está dentro~"
  1388. "~del ámbito de la clase externa, sino que está en el mismo~"
  1389. "~ámbito que la clase externa.~ Puesto que esto puede conducir"
  1390. "a confusión, es preferible no utilizar clases anidadas."
  1391. endv
  1392. beginv
  1393. centrar_coordenadas_x 7
  1394. cabecera " EJEMPLO DE CLASES ANIDADAS "
  1395. color 14 1
  1396. "char c; // ámbito exterior"
  1397. "class x // declaración de clase exterior"
  1398. "  {"
  1399. "    char c;"
  1400. "    class y // declaración de clase interior"
  1401. "      {"
  1402. "        char d;"
  1403. "        void f (char e) { c = e; }"
  1404. "      };"
  1405. "    char g (x* q) { return q->d; } // error de sintaxis "
  1406. "  };"
  1407. endv
  1408. beginvis
  1409. cabecera " COMENTARIO SOBRE EL EJEMPLO ANTERIOR "
  1410. coordenadas_completas 2 19 79 24
  1411. color 7 1
  1412. borde 2
  1413. "La función miembro f de class y, cuando usa c, está usando la c de ámbito"
  1414. "externo. Es como si class y estuviese declarada en el mismo nivel y el"
  1415. "mismo bloque interior o ámbito de fichero que class x. La función miembro"
  1416. "g de class x, cuando usa d, está intentando acceder al miembro privado de"
  1417. "class x, lo cual produce un error de compilación."
  1418. endvis
  1419. borrar_pantalla
  1420. beginv
  1421. cabecera " ESTRUCTURAS Y UNIONES "
  1422. centrar_coordenadas_x 2
  1423. color 15 1
  1424. ""
  1425. "  Hemos dicho que una estructa es simplemente una"
  1426. "  clase con todos sus miembros públicos, esto es"
  1427. ""
  1428. "  struct s { ..."
  1429. ""
  1430. "  es una forma corta de escribir"
  1431. ""
  1432. "  class s { public: ..."
  1433. ""
  1434. "  Las estructuras se usan cuando no se quiere ocultar  "
  1435. "  los datos."
  1436. ""
  1437. endv
  1438. beginv
  1439. centrar_coordenadas_x 17
  1440. color 2 1
  1441. "~Una unión (union) se define como una estructura (struct) ~"
  1442. "~donde todos sus miembros tienen la misma dirección.      ~"
  1443. endv
  1444. beginv
  1445. centrar_coordenadas_x 21
  1446. color 7 1
  1447. no_sombra
  1448. "Los especificadores de acceso de C++ (public, private"
  1449. "y protected) no pueden ser usados en las uniones."
  1450. endv
  1451. beginvis
  1452. no_multiatributo
  1453. cabecera " EJEMPLO DE union "
  1454. coordenadas_completas 3 3 78 23
  1455. color 14 1
  1456. borde 2
  1457. ""
  1458. "#include <iostream.h>"
  1459. ""
  1460. "union un"
  1461. "  {"
  1462. "    int x;"
  1463. "    float y;"
  1464. ""
  1465. "    void asigx (int xx) { x = xx; }"
  1466. "    void asigy (float yy) { y = yy; }"
  1467. "    int devx (void) { return x; }"
  1468. "    float devy (void) { return y; }"
  1469. "  };"
  1470. ""
  1471. "void main (void)"
  1472. "{"
  1473. "  un u;"
  1474. ""
  1475. "  u.x = 15;"
  1476. "  cout << u.devx () << '\n'; // imprime «15»"
  1477. ""
  1478. "  u.y = 5.5;"
  1479. "  cout << u.devy () << '\n'; // imprime «5.5»"
  1480. ""
  1481. "  u.x = 15;"
  1482. "  cout << u.devy () << '\n'; // imprime valor indefinido"
  1483. ""
  1484. "  u.y = 5.5;"
  1485. "  cout << u.devx () << '\n'; // imprime valor indefinido"
  1486. "}"
  1487. ""
  1488. endvis
  1489. partir
  1490. beginv
  1491. cabecera " PUNTEROS A MIEMBROS "
  1492. centrar_coordenadas_x 2
  1493. color 15 1
  1494. borde 2
  1495. no_sombra
  1496. "~Es posible tomar la dirección de un miembro de una clase.~"
  1497. endv
  1498. beginv
  1499. centrar_coordenadas_x 4
  1500. color 14 1
  1501. no_sombra
  1502. "Con los operadores de resolución de ámbito (~::~) y de contenido (~*~)"
  1503. "podemos declarar un puntero a un miembro de una clase."
  1504. ""
  1505. "Ejemplo:"
  1506. "  int cl::*pcl; // pcl es un puntero a un miembro entero de la clase cl"
  1507. endv
  1508. beginv
  1509. centrar_coordenadas_x 11
  1510. no_sombra
  1511. "Los operadores . y * forman un nuevo operador en C++, ~.*~, con el cual"
  1512. "referenciamos un miembro de una clase a través de un puntero al miembro"
  1513. "de esa clase."
  1514. ""
  1515. "En la siguiente ventana se muestra un ejemplo del uso de este operador."
  1516. endv
  1517. beginvis
  1518. no_multiatributo
  1519. cabecera " EJEMPLO DEL OPERADOR .* "
  1520. coordenadas_completas 1 3 80 24
  1521. color 14 1
  1522. borde 2
  1523. "#include <iostream.h>"
  1524. ""
  1525. "class cl"
  1526. "  {"
  1527. "    public:"
  1528. "      int suma;"
  1529. "      void cl::sumatorio (int x);"
  1530. "  };"
  1531. ""
  1532. "void cl::sumatorio (int x)"
  1533. "{"
  1534. "  suma = 0;"
  1535. "  for (register int i = x; i; i--)"
  1536. "    suma += i;"
  1537. "}"
  1538. ""
  1539. "void main (void)"
  1540. "{"
  1541. "  int cl::*pi;            // puntero a un miembro de cl que es de tipo int"
  1542. "  void (cl::*pf) (int x); // puntero a una función miembro de cl que"
  1543. "                          // devuelve void y acepta un int como parámetro"
  1544. "  cl clase;               // clase es un objeto de tipo cl"
  1545. ""
  1546. "  pi = &cl::suma;         // obtiene dirección del dato miembro suma"
  1547. "  pf = &cl::sumatorio;    // obtiene dirección de la función miembro"
  1548. "                          // sumatorio"
  1549. ""
  1550. "  (clase.*pf) (5);        // calcula el sumatorio de 5"
  1551. "  cout << "El sumatorio de 5 es " << clase.*pi << "\n";"
  1552. "}"
  1553. endvis
  1554. beginv
  1555. centrar_coordenadas_x 18
  1556. no_sombra
  1557. "Los operadores -> y * forman un nuevo operador en C++, ~->*~, con el cual"
  1558. "referenciamos un miembro de una clase referenciando un puntero a un"
  1559. "miembro de esa clase a través de un puntero a la clase."
  1560. ""
  1561. "En la siguiente ventana se muestra un ejemplo del uso de este operador."
  1562. endv
  1563. beginvis
  1564. no_multiatributo
  1565. cabecera " EJEMPLO DEL OPERADOR ->* "
  1566. coordenadas_completas 1 3 80 24
  1567. color 14 1
  1568. borde 2
  1569. "#include <iostream.h>"
  1570. ""
  1571. "class cl"
  1572. "  {"
  1573. "    public:"
  1574. "      int suma;"
  1575. "      void cl::sumatorio (int x);"
  1576. "  };"
  1577. ""
  1578. "void cl::sumatorio (int x)"
  1579. "{"
  1580. "  suma = 0;"
  1581. "  for (register int i = x; i; i--)"
  1582. "    suma += i;"
  1583. "}"
  1584. ""
  1585. "void main (void)"
  1586. "{"
  1587. "  int cl::*pi;            // puntero a un miembro de cl que es de tipo int"
  1588. "  void (cl::*pf) (int x); // puntero a una función miembro de cl que"
  1589. "                          // devuelve void y acepta un int como parámetro"
  1590. "  cl clase;               // clase es un objeto de tipo cl"
  1591. "  cl *pcl;                // pcl es un puntero a un objeto del tipo cl"
  1592. ""
  1593. "  pcl = &clase;           // asigna a pcl la dirección del objeto clase"
  1594. ""
  1595. "  pi = &cl::suma;         // obtiene dirección del dato miembro suma"
  1596. "  pf = &cl::sumatorio;    // obtiene dirección de la función miembro"
  1597. "                          // sumatorio"
  1598. ""
  1599. "  (pcl->*pf) (5);         // calcula el sumatorio de 5 usando -> para llamar"
  1600. "                          // a la función"
  1601. "  cout << "El sumatorio de 5 es " << pcl->*pi << "\n"; // usa -> para acceder"
  1602. "                                                       // a un dato miembro"
  1603. "}"
  1604. endvis
  1605. beginvis
  1606. no_multiatributo
  1607. cabecera " PRECEDENCIA DE OPERADORES "
  1608. coordenadas_completas 1 2 80 24
  1609. color 0 3
  1610. borde 2
  1611. ""
  1612. "Una vez vistos todos los operadores que añade el C++ al lenguaje C (new,"
  1613. "(delete, ::, .*, ->*) vamos a mostrar la tabla de precedencia completa de"
  1614. "los operadores de C++."
  1615. ""
  1616. ""
  1617. " ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
  1618. "  Precedencia de Operadores"
  1619. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  1620. ""
  1621. "En la siguiente tabla de precedencia de operadores, los operadores son"
  1622. "divididos en 16 categorías."
  1623. ""
  1624. "La categoría #1 tiene la precedencia más alta; la categoría #2 (operadores"
  1625. "unarios) toma la segunda precedencia, y así hasta el operador coma, el"
  1626. "cual tiene la precedencia más baja."
  1627. ""
  1628. "Los operadores que están dentro de una misma categoría tienen igual"
  1629. "precedencia."
  1630. ""
  1631. "Los operadores unarios (categoría #2), condicional (categoría #14), y"
  1632. "de asignación (categoría #15) se asocian de derecha a izquierda; todos"
  1633. "los demás operadores se asocian de izquierda a derecha."
  1634. ""
  1635. "════════════════╤══════════╤════════════════════════════════════════════════"
  1636. "  #  Categoría  │ Operador │ Qué es (o hace)"
  1637. "════════════════╪══════════╪════════════════════════════════════════════════"
  1638. "  1. Más alto   │    ()    │ Llamada a función"
  1639. "                │    []    │ Indexamiento de array"
  1640. "                │    ->    │ Selector de componente indirecta de C++"
  1641. "                │    ::    │ Resolución/acceso de ámbito de C++"
  1642. "                │     .    │ Selector de componente directa de C++"
  1643. "────────────────┼──────────┼────────────────────────────────────────────────"
  1644. "  2. Unario     │     !    │ Negación Lógica (NO)"
  1645. "                │     ~    │ Complemento a 1"
  1646. "                │     +    │ Más unario"
  1647. "                │     -    │ Menos unario"
  1648. "                │    ++    │ Preincremento o postincremento"
  1649. "                │    --    │ Predecremento o postdecremento"
  1650. "                │     &    │ Dirección"
  1651. "                │     *    │ Contenido (indirección)"
  1652. "                │  sizeof  │ (devuelve tamaño de operando, en bytes)"
  1653. "                │    new   │ (asignador de memoria dinámica en C++)"
  1654. "                │  delete  │ (desasignador de memoria dinámica en C++)"
  1655. "────────────────┼──────────┼────────────────────────────────────────────────"
  1656. "  3. Multipli-  │     *    │ Multiplica"
  1657. "     cativo     │     /    │ Divide"
  1658. "                │     %    │ Resto (módulo)"
  1659. "────────────────┼──────────┼────────────────────────────────────────────────"
  1660. "  4. Acceso a   │    .*    │ Operador de referencia de una dirección en C++."
  1661. "   los miembros │    ->*   │ Operador de referencia de una dirección en C++."
  1662. "────────────────┼──────────┼────────────────────────────────────────────────"
  1663. "  5. Aditivo    │     +    │ Más binario"
  1664. "                │     -    │ Menos binario"
  1665. "────────────────┼──────────┼────────────────────────────────────────────────"
  1666. "  6. Desplaza-  │    <<    │ Desplazamiento a la izquierda"
  1667. "     miento     │    >>    │ Desplazamiento a la derecha"
  1668. "────────────────┼──────────┼────────────────────────────────────────────────"
  1669. "  7. Relacional │     <    │ Menor que"
  1670. "                │    <=    │ Menor o igual que"
  1671. "                │     >    │ Mayor que"
  1672. "                │    >=    │ Mayor o igual que"
  1673. "────────────────┼──────────┼────────────────────────────────────────────────"
  1674. "  8. Igualdad   │    ==    │ Igual a"
  1675. "                │    !=    │ Distinto a"
  1676. "────────────────┼──────────┼────────────────────────────────────────────────"
  1677. "  9.            │     &    │ AND entre bits"
  1678. "────────────────┼──────────┼────────────────────────────────────────────────"
  1679. " 10.            │     ^    │ XOR entre bits"
  1680. "────────────────┼──────────┼────────────────────────────────────────────────"
  1681. " 11.            │     |    │ OR entre bits"
  1682. "────────────────┼──────────┼────────────────────────────────────────────────"
  1683. " 12.            │    &&    │ AND lógico"
  1684. "────────────────┼──────────┼────────────────────────────────────────────────"
  1685. " 13.            │    ||    │ OR lógico"
  1686. "────────────────┼──────────┼────────────────────────────────────────────────"
  1687. " 14. Condicional│    ?:    │(a ? x : y significa "si a entonces x, si no y")"
  1688. "────────────────┼──────────┼────────────────────────────────────────────────"
  1689. " 15. Asignación │     =    │ Asignación simple"
  1690. "                │    *=    │ Asignar producto"
  1691. "                │    /=    │ Asignar cociente"
  1692. "                │    %=    │ Asignar resto (módulo)"
  1693. "                │    +=    │ Asignar suma"
  1694. "                │    -=    │ Asignar diferncia"
  1695. "                │    &=    │ Asignar AND entre bits"
  1696. "                │    ^=    │ Asignar XOR entre bits"
  1697. "                │    |=    │ Asignar OR entre bits"
  1698. "                │   <<=    │ Asignar desplazamiento hacia la izquierda"
  1699. "                │   >>=    │ Asignar desplazamiento hacia la derecha"
  1700. "────────────────┼──────────┼────────────────────────────────────────────────"
  1701. " 16. Coma       │     ,    │ Evaluar"
  1702. "════════════════╧══════════╧════════════════════════════════════════════════"
  1703. ""
  1704. "Todos los operadores de la tabla se pueden sobrecargar (referencia de sobre-"
  1705. "carga de operadores en lección 5 del tutor de C++) excepto los siguientes:"
  1706. ""
  1707. "       .     Selector de componente directa de C++"
  1708. "      .*     Referencia en C++"
  1709. "      ::     Resolución/acceso de ámbito en C++"
  1710. "      ?:     Condicional"
  1711. ""
  1712. endvis
  1713. end lección 3
  1714.  
  1715. ; LECCION 4
  1716. begin
  1717. beginv
  1718. borde 2
  1719. color 1 7
  1720. centrar_coordenadas
  1721. cabecera " CONSTRUCTORES Y DESTRUCTORES "
  1722. ""
  1723. "  ~ Esta lección gira en torno a los constructores ~  "
  1724. "  ~ y destructores.                                ~"
  1725. ""
  1726. "  ~ Un constructor es una función miembro de un    ~"
  1727. "  ~ objeto que es llamada automáticamente cuando   ~"
  1728. "  ~ se crea el objeto. Tiene el mismo nombre de    ~"
  1729. "  ~ la clase.                                      ~"
  1730. ""
  1731. "  ~ Un destructor es una función miembro de un     ~"
  1732. "  ~ objeto que es llamada automáticamente cuando   ~"
  1733. "  ~ se destruye el objeto. Tiene el mismo nombre   ~"
  1734. "  ~ de la clase precedido por ~~.                   ~"
  1735. ""
  1736. endv
  1737. beginv
  1738. centrar_coordenadas
  1739. cabecera " INDICE DE ESTA LECCION "
  1740. ""
  1741. "  En esta lección se va a estudiar los siguientes puntos:   "
  1742. ""
  1743. "  - Concepto de constructor y destructor."
  1744. "  - Constructores y destructores de objetos estáticos."
  1745. "  - Almacenamiento libre."
  1746. "  - Vectores de objetos de clase."
  1747. "  - Objetos como miembros."
  1748. "  - Autorreferencia: el puntero this."
  1749. "  - Funciones miembros constantes."
  1750. "  - Funciones miembros volátiles."
  1751. ""
  1752. endv
  1753. borrar_pantalla
  1754. beginv
  1755. cabecera " CONCEPTO DE CONSTRUCTOR Y DESTRUCTOR "
  1756. color 15 2
  1757. centrar_coordenadas_x 2 2
  1758. borde 2
  1759. ""
  1760. "  Un ~constructor~ es una función miembro que tiene el mismo nombre  "
  1761. "  que la clase. Los constructores se utilizan normalmente para"
  1762. "  inicializar datos miembros y asignar memoria usando new. Un"
  1763. "  ~destructor~ es una función miembro que tiene el mismo nombre que"
  1764. "  la clase precedido por el carácter ~~. Los destructores se uti-"
  1765. "  lizan normalmente para liberar, usando delete, la memoria asig-"
  1766. "  nada por el constructor."
  1767. ""
  1768. endv
  1769. beginv
  1770. centrar_coordenadas_x 14
  1771. borde 1
  1772. "Los constructores pueden sobrecargarse y pueden tomar argumentos;"
  1773. "en los destructores no se permite ninguna de estas dos cosas. Los"
  1774. "constructores y los destructores no devuelven nada."
  1775. endv
  1776. beginv
  1777. centrar_coordenadas_x 19
  1778. "Los constructores son invocados automáticamente cuando se crea el"
  1779. "objeto. Los destructores son invocados automáticamente cuando se"
  1780. "destruye el objeto."
  1781. endv
  1782. beginv
  1783. cabecera " EJEMPLO DE CONSTRUCTOR "
  1784. ;coordenadas_completas 3 3 78 23
  1785. coordenadas 1 3
  1786. color 15 4
  1787. borde 2
  1788. ""
  1789. "#include <iostream.h>"
  1790. ""
  1791. "class clase"
  1792. "  {"
  1793. "    int x;"
  1794. ""
  1795. "    public:"
  1796. "      clase (int i) { x = i; }"
  1797. "      int devx (void) { return x; }"
  1798. "  };"
  1799. ""
  1800. "void main (void)"
  1801. "{"
  1802. "  clase c1; // error de compilación"
  1803. "  clase c2 (2);"
  1804. "  cout << c2.devx (); // imprime «2»"
  1805. "}"
  1806. ""
  1807. endv
  1808. beginv
  1809. cabecera " EJ. DE CONSTR. CON ARGS. POR DEFECTO "
  1810. ;coordenadas_completas 3 3 78 23
  1811. coordenadas 41 3
  1812. color 15 4
  1813. borde 2
  1814. ""
  1815. "#include <iostream.h>"
  1816. ""
  1817. "class clase"
  1818. "  {"
  1819. "    int x;"
  1820. ""
  1821. "    public:"
  1822. "      clase (int i = 0) { x = i; }"
  1823. "      int devx (void) { return x; }"
  1824. "  };"
  1825. ""
  1826. "void main (void)"
  1827. "{"
  1828. "  clase c1, c2 (1);"
  1829. "  cout << c1.devx (); // imprime «0»"
  1830. "  cout << c2.devx (); // imprime «1»"
  1831. "}"
  1832. ""
  1833. endv
  1834. beginvis
  1835. no_multiatributo
  1836. no_posicion
  1837. cabecera " EJEMPLO DE CONSTRUCTOR SOBRECARGADO "
  1838. coordenadas_completas 3 4 78 24
  1839. color 14 4
  1840. borde 2
  1841. no_sombra
  1842. ""
  1843. "#include <iostream.h>"
  1844. ""
  1845. "class clase"
  1846. "  {"
  1847. "    int x;"
  1848. ""
  1849. "    public:"
  1850. "      clase (void) { x = 0; }"
  1851. "      clase (int i) { x = i; }"
  1852. "      int devx (void) { return x; }"
  1853. "  };"
  1854. ""
  1855. "void main (void)"
  1856. "{"
  1857. "  clase c1;"
  1858. "  clase c2 (5);"
  1859. "  clase c3 (); // atención: esto es el prototipo de una función"
  1860. "  cout << c1.devx (); // imprime «0»"
  1861. "  cout << c2.devx (); // imprime «5»"
  1862. "  cout << c3.devx (); // error de compilación: c3 no es objeto sino func."
  1863. "}"
  1864. ""
  1865. endvis
  1866. beginvis
  1867. no_multiatributo
  1868. no_posicion
  1869. cabecera " EJEMPLO DE CONSTRUCTOR Y DESTRUCTOR "
  1870. coordenadas_completas 3 3 78 24
  1871. color 14 1
  1872. borde 2
  1873. no_sombra
  1874. ""
  1875. "#include <iostream.h> // para utilizar: cout, << sobrecargado"
  1876. ""
  1877. "enum boolean { false, true };"
  1878. ""
  1879. "class pila"
  1880. "  {"
  1881. "    private:    // representación oculta para el TAD pila"
  1882. ""
  1883. "      char *s;"
  1884. "      int longit_max;"
  1885. "      int cima;"
  1886. ""
  1887. "    public:    // interface pública para el TAD pila"
  1888. ""
  1889. "      pila (void) { s = new char[100]; longit_max = 100; cima = 0; }"
  1890. "      pila (int tam) { s = new char[tam]; longit_max = tam; cima = 0; }"
  1891. "      pila (int tam, char str[]);"
  1892. "      ~pila (void) { delete s; }"
  1893. "      void inicializar (void) { cima = 0; }"
  1894. "      void meter (char c) { s[++cima] = c; }"
  1895. "      char sacar (void) { return (s[cima--]); }"
  1896. "      char elem_cima (void) { return (s[cima]); }"
  1897. "      boolean vacia (void) { return boolean (cima == 0); }"
  1898. "      boolean llena (void) { return boolean (cima == longit_max - 1); }"
  1899. "  };"
  1900. ""
  1901. "pila::pila (int tam, char str[])"
  1902. "{"
  1903. "  s = new char[tam];"
  1904. "  longit_max = tam;"
  1905. "  for (register int i = 0; i < longit_max && str[i] != 0; i++)"
  1906. "    s[i+1] = str[i];"
  1907. "  cima = i;"
  1908. "}"
  1909. ""
  1910. "void main (void)"
  1911. "{"
  1912. "  char *cad = "Ejemplo";"
  1913. "  pila p (20, cad);"
  1914. ""
  1915. "  cout << "Cadena original: " << cad << "\n"; // imprime «Ejemplo»"
  1916. "  cout << "Cadena invertida: ";"
  1917. "  while (! p.vacia ())                        // imprime «olpmejE»"
  1918. "    cout << p.sacar ();"
  1919. "  cout << "\n";"
  1920. "}"
  1921. ""
  1922. endvis
  1923. borrar_pantalla
  1924. beginv
  1925. cabecera " CONSTRUCTORES Y DESTRUCTORES DE OBJETOS ESTATICOS "
  1926. centrar_coordenadas_x 2
  1927. color 15 5
  1928. ""
  1929. "  En algunas implementaciones está indefinido si el constructor"
  1930. "  para un objeto estático local es llamado o no en la función que"
  1931. "  es declarado. Esto quiere decir que los argumentos de los cons-"
  1932. "  tructores para objetos estáticos deben ser expresiones contantes  "
  1933. "  en tales implementaciones. Por ejemplo:"
  1934. ""
  1935. "    void f (int a)"
  1936. "    {"
  1937. "      static clase c (a); // error en algunos sistemas"
  1938. "    }"
  1939. ""
  1940. endv
  1941. begint
  1942. beginv
  1943. cabecera " EJEMPLO DE FUNCIONAMIENTO DE OBJETOS ESTATICOS LOCALES EN TURBO C++ "
  1944. color 14 5
  1945. coordenadas_completas 1 3 80 24
  1946. "#include <iostream.h>"
  1947. ""
  1948. "class clase"
  1949. "  {"
  1950. "    public:"
  1951. "      int x;"
  1952. "      clase (int i) { x = i; }"
  1953. "  };"
  1954. ""
  1955. "void f (int a)"
  1956. "{"
  1957. "  static clase c (a); // el constructor es invocado en primera llamada a f()"
  1958. "  cout << c.x;"
  1959. "}"
  1960. ""
  1961. "void main (void)"
  1962. "{"
  1963. "  f (10); // imprime «10»"
  1964. "  f (20); // imprime «10»"
  1965. "}"
  1966. endv
  1967. endt
  1968. beginv
  1969. color 0 5
  1970. centrar_coordenadas_x 16
  1971. "Si un programa termina usando la función exit(), se llamará a los"
  1972. "destructores para los objetos estáticos, pero si el programa ter-"
  1973. "mina usando la función abort(), no se llamará a tales destructores."
  1974. "Notad que esto implica que exit() no termina un programa inmediata- "
  1975. "mente. LLamar a exit() en un destructor puede causar una recursión"
  1976. "infinita."
  1977. endv
  1978. borrar_pantalla
  1979. beginvis
  1980. no_multiatributo
  1981. cabecera " ALMACENAMIENTO LIBRE "
  1982. coordenadas_completas 3 2 78 23
  1983. color 15 3
  1984. borde 2
  1985. "Consideremos el ejemplo:"
  1986. ""
  1987. "  #include <iostream.h>"
  1988. ""
  1989. "  class clase"
  1990. "    {"
  1991. "      char *s;"
  1992. ""
  1993. "      public:"
  1994. "        clase (int n) { s = new char[n]; }"
  1995. "        ~clase (void) { delete s; }"
  1996. "    };"
  1997. ""
  1998. "  void main (void)"
  1999. "  {"
  2000. "    clase *p = new clase (10);"
  2001. "    clase *q = new clase (20);"
  2002. "    delete p;"
  2003. "    delete p; // posiblemente un error en tiempo de ejecución"
  2004. "  }"
  2005. ""
  2006. "El constructor clase::clase() será llamado dos veces, así como también"
  2007. "el destructor clase::~clase(). El C++ no ofrece ninguna garantía de que"
  2008. "el destructor será llamado para un objeto creado con new, a no ser que"
  2009. "se utilice delete. El programa anterior no libera nunca q, pero libera"
  2010. "dos veces p. Dependiendo del tipo de p y de q, el programador puede o"
  2011. "no considerar esto un error. No liberar un objeto no es normalmente un"
  2012. "error, sino que se considera malgastar memoria. Liberar dos veces p es"
  2013. "normalmente un error serio. El resultado típico de aplicar delete al"
  2014. "mismo puntero dos veces es un bucle infinito en la rutina de gestión de"
  2015. "almacenamiento libre, pero el comportamiento en este caso no está espe-"
  2016. "cificado por la definición del lenguaje y depende de la implementación."
  2017. endvis
  2018. borrar_pantalla
  2019. beginv
  2020. cabecera " VECTORES DE OBJETOS DE CLASE "
  2021. centrar_coordenadas_x 2
  2022. color 15 6
  2023. ""
  2024. "  Para declarar un vector de objetos de una clase con un constructor,  "
  2025. "  esa clase debe tener un constructor que pueda ser llamado sin una"
  2026. "  lista de argumentos. Ni siquiera pueden ser usados los argumentos"
  2027. "  por defecto."
  2028. ""
  2029. endv
  2030. beginvis
  2031. no_multiatributo
  2032. cabecera " EJEMPLO DE VECTORES DE OBJETOS "
  2033. coordenadas_completas 3 10 77 23
  2034. color 14 6
  2035. borde 2
  2036. ""
  2037. "#include <iostream.h>"
  2038. ""
  2039. "class cl1"
  2040. "  {"
  2041. "    int x;"
  2042. ""
  2043. "    public:"
  2044. "      cl1 (int i) { x = i; }"
  2045. "      int devx (void) { return x; }"
  2046. "  };"
  2047. ""
  2048. "class cl2"
  2049. "  {"
  2050. "    int x;"
  2051. ""
  2052. "    public:"
  2053. "      cl2 (int i = 0) { x = i; }"
  2054. "      int devx (void) { return x; }"
  2055. "  };"
  2056. ""
  2057. "class cl3"
  2058. "  {"
  2059. "    int x;"
  2060. ""
  2061. "    public:"
  2062. "      cl3 (void) { x = 0; }"
  2063. "      cl3 (int i) { x = i; }"
  2064. "      int devx (void) { return x; }"
  2065. "  };"
  2066. ""
  2067. "class cl4"
  2068. "  {"
  2069. "    int x;"
  2070. ""
  2071. "    public:"
  2072. "      void asigx (int i) { x = i; }"
  2073. "      int devx (void) { return x; }"
  2074. "  };"
  2075. ""
  2076. "cl1 vcl1[10]; // ilegal: error en compilación"
  2077. "cl2 vcl2[10]; // ilegal: error en compilación"
  2078. "cl3 vcl3[10];"
  2079. "cl4 vcl4[10];"
  2080. ""
  2081. "void main (void)"
  2082. "{"
  2083. "  vcl4[6].asigx(1);"
  2084. "  cout << vcl3[5].devx() << " " << vcl4[6].devx(); // imprime «0 1»"
  2085. "}"
  2086. ""
  2087. endvis
  2088. beginv
  2089. color 0 6
  2090. centrar_coordenadas_x 12
  2091. ""
  2092. "  Para vectores que no son asignados usando new, el destructor es  "
  2093. "  llamado implícitamente para cada elemento del vector cuando ese"
  2094. "  vector es destruido. Sin embargo, esto no se puede hacer implí-"
  2095. "  citamente para vectores creados con new, ya que el compilador"
  2096. "  no puede distinguir el puntero a un simple objeto del puntero"
  2097. "  al primer elemento de un vector de objetos."
  2098. ""
  2099. endv
  2100. beginvis
  2101. no_multiatributo
  2102. no_posicion
  2103. cabecera " EJEMPLO DE LLAMADAS A DESTRUCTORES EN VECTORES DE OBJETOS "
  2104. coordenadas_completas 3 3 78 23
  2105. color 14 6
  2106. borde 2
  2107. ""
  2108. "#include <iostream.h>"
  2109. ""
  2110. "const int n = 3;"
  2111. ""
  2112. "class clase"
  2113. "  {"
  2114. "    public:"
  2115. "      static int contc, contd;"
  2116. "      clase (void) { cout << 'c' << ++contc << ' '; }"
  2117. "      ~clase (void) { cout << 'd' << ++contd << ' '; }"
  2118. "  };"
  2119. ""
  2120. "int clase::contc, clase::contd;"
  2121. ""
  2122. "void f (void)"
  2123. "{"
  2124. "  clase *p = new clase;"
  2125. "  clase *q = new clase[n];"
  2126. "  delete p; // una clase"
  2127. "  delete q; // problema: n clases"
  2128. "}"
  2129. ""
  2130. "void g (void)"
  2131. "{"
  2132. "  clase *p = new clase;"
  2133. "  clase *q = new clase[n];"
  2134. "  delete p;"
  2135. "  delete [n] q;"
  2136. "}"
  2137. ""
  2138. "void h (void)"
  2139. "{"
  2140. "  clase c1;"
  2141. "  clase vc2[n];"
  2142. "}"
  2143. ""
  2144. "void main (void)"
  2145. "{"
  2146. "  clase::contc = clase::contd = 0;"
  2147. "  cout << '\n';"
  2148. "  f (); // imprime «c1 c2 c3 c4 d1 d2»"
  2149. ""
  2150. "  clase::contc = clase::contd = 0;"
  2151. "  cout << '\n';"
  2152. "  g (); // imprime «c1 c2 c3 c4 d1 d2 d3 d4»"
  2153. ""
  2154. "  clase::contc = clase::contd = 0;"
  2155. "  cout << '\n';"
  2156. "  h (); // imprime «c1 c2 c3 c4 d1 d2 d3 d4»"
  2157. "}"
  2158. ""
  2159. endvis
  2160. borrar_pantalla
  2161. beginv
  2162. cabecera " OBJETOS COMO MIEMBROS "
  2163. centrar_coordenadas_x 2
  2164. color 15 2
  2165. ""
  2166. "  Los objetos (ya sean clases, estructuras o uniones), al igual  "
  2167. "  que cualquier variable, pueden ser miembros de otros objetos."
  2168. ""
  2169. endv
  2170. beginv
  2171. centrar_coordenadas_x 10
  2172. color 14 2
  2173. ""
  2174. "  Los constructores de los objetos miembros pueden ser invocados"
  2175. "  entre el nombre de la definición (no declaración) del construc-  "
  2176. "  tor del objeto y la llave de apertura de la definición de la"
  2177. "  función constructora. Si se van a invocar varios constructores"
  2178. "  de objetos miembros, estas llamadas se separan por comas."
  2179. ""
  2180. endv
  2181. beginvis
  2182. no_multiatributo
  2183. cabecera " EJEMPLO DE OBJETOS COMO MIEMBROS "
  2184. coordenadas_completas 1 3 80 24
  2185. color 4 2
  2186. borde 2
  2187. "/*"
  2188. "  Este programa imprime:"
  2189. "  c1_1  c1_2  c1_3  c2_1  x2_10  x1_10  x1_10  x1_10  d2_1  d1_1  d1_2  d1_32"
  2190. "*/"
  2191. ""
  2192. "#include <iostream.h>"
  2193. ""
  2194. "class cl1"
  2195. "  {"
  2196. "    static int contc1, contd1;"
  2197. "    int x1;"
  2198. ""
  2199. "    public:"
  2200. "      cl1 (int i) { x1 = i; cout << "c1_" << ++contc1 << "  "; }"
  2201. "      ~cl1 (void) { cout << "d1_" << ++contd1 << "  "; }"
  2202. "      void impr (void) { cout << "x1_" << x1 << "  "; }"
  2203. "  };"
  2204. ""
  2205. "int cl1::contc1 = 0, cl1::contd1 = 0;"
  2206. ""
  2207. "class cl2"
  2208. "  {"
  2209. "    static int contc2, contd2;"
  2210. "    int x2;"
  2211. "    cl1 a, b, c;"
  2212. ""
  2213. "    public:"
  2214. "      cl2 (int i): a (i), b (i), c (i)"
  2215. "        { x2 = i; cout << "c2_" << ++contc2 << "  "; }"
  2216. "      ~cl2 (void) { cout << "d2_" << ++contd2 << "  "; }"
  2217. "      void impr (void) { cout << "x2_" << x2 << "  "; }"
  2218. "      void impra (void) { a.impr (); }"
  2219. "      void imprb (void) { b.impr (); }"
  2220. "      void imprc (void) { c.impr (); }"
  2221. "  };"
  2222. ""
  2223. "int cl2::contc2 = 0, cl2::contd2 = 0;"
  2224. ""
  2225. "void main (void)"
  2226. "{"
  2227. "  cl2 c (10);"
  2228. "  c.impr ();"
  2229. "  c.impra ();"
  2230. "  c.imprb ();"
  2231. "  c.imprc ();"
  2232. "}"
  2233. ""
  2234. "/*"
  2235. "  Si no queremos que el constructor cl2 sea inline, haríamos:"
  2236. ""
  2237. "  class cl2"
  2238. "    {"
  2239. "      ..."
  2240. "      public"
  2241. "        cl2 (int i);"
  2242. "      ..."
  2243. "    };"
  2244. ""
  2245. "  cl2::cl2 (int i): a (i), b (i), c (i)"
  2246. "  {"
  2247. "    x2 = i;"
  2248. "    cout << "c2_" << ++contc2 << "  ";"
  2249. "  }"
  2250. "*/"
  2251. endvis
  2252. borrar_pantalla
  2253. beginv
  2254. cabecera " AUTORREFERENCIA: EL PUNTERO this "
  2255. centrar_coordenadas_x 2
  2256. color 15 3
  2257. "La palabra clave ~this~ denota un puntero autorreferencial declarado"
  2258. "implícitamente. Puede ser usado en cualquier función miembro."
  2259. endv
  2260. beginv
  2261. centrar_coordenadas_x 8
  2262. color 14 3
  2263. "A todas las funciones miembros de un objeto se les pasa un argumento"
  2264. "oculto: this. Este argumento implícito siempre apunta al objeto para"
  2265. "el cual se ha invocado la función miembro."
  2266. endv
  2267. beginvis
  2268. no_multiatributo
  2269. cabecera " EJEMPLO DEL PUNTERO this "
  2270. coordenadas_completas 3 3 78 23
  2271. color 1 3
  2272. borde 2
  2273. ""
  2274. "#include <iostream.h>"
  2275. ""
  2276. "class x"
  2277. "  {"
  2278. "    int a, b;"
  2279. ""
  2280. "    public:"
  2281. "      x (int aa, int bb) { a = aa; b = bb; }"
  2282. "      int leera (void) { return a; } // devuelve el valor de x::a"
  2283. "      int leerb (void) { return this->b; } // devuelve el valor de x::b"
  2284. "  };"
  2285. ""
  2286. "void main (void)"
  2287. "{"
  2288. "  x x (1, 2);"
  2289. "  cout << x.leera () << x.leerb (); // imprime «12»"
  2290. "}"
  2291. ""
  2292. endvis
  2293. borrar_pantalla
  2294. beginv
  2295. cabecera " FUNCIONES MIEMBROS CONSTANTES "
  2296. centrar_coordenadas_x 2
  2297. color 15 4
  2298. "~Una función miembro constante no modifica los datos miembros de un objeto.~"
  2299. ""
  2300. "~Una función miembro constante es el único tipo de función miembro que~"
  2301. "~puede ser llamada por un objeto constante.                           ~"
  2302. ""
  2303. "~Una función miembro constante puede ser llamada también por objetos no~"
  2304. "~constantes.                                                           ~"
  2305. ""
  2306. "~No se puede calificar una definición de función con const y entonces~"
  2307. "~intentar modificar los datos miembros (esto generará un error).     ~"
  2308. ""
  2309. "~Para crear una función miembro constante hay que colocar el calificador~"
  2310. "~const después de la lista de argumentos y antes de abrir la llave de   ~"
  2311. "~definición de la función.                                              ~"
  2312. ""
  2313. "~Las funciones miembros constantes sólo pueden llamar a otras funciones~"
  2314. "~miembros constantes.                                                  ~"
  2315. ""
  2316. "~Los constructores y los destructores no necesitan ser declarados funciones~"
  2317. "~miembros constantes para que sean invocados por objetos constantes.       ~"
  2318. endv
  2319. beginvis
  2320. no_multiatributo
  2321. no_posicion
  2322. cabecera " EJEMPLO DE USO CORRECTO Y INCORRECTO DE FUNCIONES MIEMBROS CONSTANTES "
  2323. coordenadas_completas 1 3 80 24
  2324. color 14 4
  2325. borde 2
  2326. "// Ejemplo de funciones miembros constantes y objetos constantes"
  2327. ""
  2328. "class clase"
  2329. "  {"
  2330. "    private:"
  2331. "      int x;"
  2332. ""
  2333. "    public:"
  2334. "      clase (void) { x = 0; }"
  2335. ""
  2336. "      ~clase () { }"
  2337. "      int dev (void) const { return x; }   // CORRECTO: función constante no"
  2338. "                                           // modifica ningún miembro"
  2339. "      void incr (void) { x++; }            // CORRECTO: función miembro"
  2340. "                                           // ordinaria (no constante)"
  2341. ""
  2342. "/*"
  2343. "      clase (int i) const { x = i; }       // ERROR: función constante"
  2344. "                                           // modificando miembro"
  2345. "      void incr2 (void) const { x++; }     // ERROR: función constante"
  2346. "                                           // modificando miembro"
  2347. "      void incr3 (void) const { incr (); } // ERROR: función constante"
  2348. "                                           // llama a función no constante"
  2349. "*/"
  2350. "  };"
  2351. ""
  2352. "void main (void)"
  2353. "{"
  2354. "  const clase cl1; // cl1 es un objeto constante"
  2355. ""
  2356. "  cl1.dev ();      // CORRECTO: función constante llamada por objeto"
  2357. "                   // constante"
  2358. "/*"
  2359. "  cl1.incr ();     // ERROR: función no constante llamada por objeto"
  2360. "                   // constante"
  2361. "*/"
  2362. ""
  2363. "  clase cl2;       // cl2 es un objeto ordinario (no constante)"
  2364. "  cl2.dev ();      // CORRECTO: función constante llamada por objeto no"
  2365. "                   // constante"
  2366. "  cl2.incr ();     // CORRECTO: función no constante llamada por objeto no"
  2367. "                   // constante"
  2368. "}"
  2369. endvis
  2370. borrar_pantalla
  2371. beginv
  2372. cabecera " FUNCIONES MIEMBROS VOLATILES "
  2373. centrar_coordenadas_x 2
  2374. color 15 6
  2375. "~Las funciones miembros volátiles son análogas a las funciones miembros~"
  2376. "~constantes, y son creadas de la misma forma, colocando el calificador ~"
  2377. "~volatile después de la lista de argumentos y antes del cuerpo de la   ~"
  2378. "~función.                                                              ~"
  2379. ""
  2380. "~Sólo funciones miembros volátiles pueden ser llamadas por objetos~"
  2381. "~volátiles, y las funciones miembros volátiles pueden sólo llamar ~"
  2382. "~a otras funciones miembros volátiles.                            ~"
  2383. ""
  2384. "~Al contrario que las funciones miembros constantes, las funciones   ~"
  2385. "~miembros volátiles pueden modificar los datos miembros de un objeto.~"
  2386. ""
  2387. "~Los constructores y los destructores no necesitan ser declarados      ~"
  2388. "~funciones miembros volátiles para ser invocados por objetos volátiles.~"
  2389. ""
  2390. "~Una función miembro puede ser constante y volátil.~"
  2391. endv
  2392. beginvis
  2393. no_multiatributo
  2394. no_posicion
  2395. cabecera " EJEMPLO DE USO CORRECTO Y INCORRECTO DE FUNCIONES MIEMBROS VOLATILES "
  2396. coordenadas_completas 1 3 80 24
  2397. color 14 6
  2398. borde 2
  2399. "// Ejemplo de funciones miembros volátiles y objetos volátiles"
  2400. ""
  2401. "class clase"
  2402. "  {"
  2403. "    private:"
  2404. "      int x;"
  2405. ""
  2406. "    public:"
  2407. "      clase (void) { x = 0; }                 // constructor no volátil"
  2408. "      clase (int i) volatile { x = i; }       // constructor volátil"
  2409. ""
  2410. "      ~clase () { }                           // destructor no volátil"
  2411. "      int dev (void) volatile { return x; }   // función miembro volátil"
  2412. "      void incr (void) { x++; }               // función miembro no volátil"
  2413. "/*"
  2414. "      void incr2 (void) volatile { incr (); } // ERROR: función volátil"
  2415. "                                              // llama a función no volátil"
  2416. "*/"
  2417. "  };"
  2418. ""
  2419. "void main (void)"
  2420. "{"
  2421. "  volatile clase cl1; // cl1 es un objeto volátil"
  2422. ""
  2423. "  cl1.dev ();      // CORRECTO: función volátil llamada por objeto"
  2424. "                   // volátil"
  2425. "/*"
  2426. "  cl1.incr ();     // ERROR: función no volátil llamada por objeto"
  2427. "                   // volátil"
  2428. "*/"
  2429. "  clase cl2;       // cl2 es un objeto ordinario (no volátil)"
  2430. "  cl2.dev ();      // CORRECTO: función volátil llamada por objeto no"
  2431. "                   // volátil"
  2432. "  cl2.incr ();     // CORRECTO: función no volátil llamada por objeto no"
  2433. "                   // volátil"
  2434. "}"
  2435. endvis
  2436. borrar_pantalla
  2437. beginvis
  2438. no_multiatributo
  2439. no_posicion
  2440. cabecera " ALGUNAS DECLARACIONES DE CLASES CURIOSAS "
  2441. coordenadas_completas 3 3 78 23
  2442. color 7 0
  2443. borde 2
  2444. ""
  2445. "#include <iostream.h>"
  2446. ""
  2447. "class clase1"
  2448. "  {"
  2449. "    public:"
  2450. "      int i;"
  2451. "      float f;"
  2452. "      int devi (void) { return i; }"
  2453. "      float devf (void) { return f; }"
  2454. "  };"
  2455. ""
  2456. "void f (void)"
  2457. "{"
  2458. "  clase1 c = { 10, 20.35 };"
  2459. "  cout << c.devi () << ' ' << c.devf () << '\n'; // imprime «10 20.35»"
  2460. "}"
  2461. ""
  2462. "class clase2"
  2463. "  {"
  2464. "   int a, b;"
  2465. ""
  2466. "    public:"
  2467. "      clase2 (int i, int j): a (i), b (i + j) { }"
  2468. "      int deva (void) { return a; }"
  2469. "      int devb (void) { return b; }"
  2470. "  };"
  2471. ""
  2472. "void g (void)"
  2473. "{"
  2474. "  clase2 c (1, 2);"
  2475. "  cout << c.deva () << ' ' << c.devb () << '\n'; // imprime «1 3»"
  2476. "}"
  2477. ""
  2478. "class clase3"
  2479. "  {"
  2480. "    int a, b;"
  2481. ""
  2482. "    public:"
  2483. "      clase3 (int i, int j): a (i) { b = j; }"
  2484. "      int deva (void) { return a; }"
  2485. "      int devb (void) { return b; }"
  2486. "  };"
  2487. ""
  2488. "void h (void)"
  2489. "{"
  2490. "  clase3 c (2, 3);"
  2491. "  cout << c.deva () << ' ' << c.devb () << '\n'; // imprime «2 3»"
  2492. "}"
  2493. ""
  2494. "class clase4"
  2495. "  {"
  2496. "    public:"
  2497. "      int d;"
  2498. "      float f;"
  2499. "      int devd (void) const volatile { return d; }"
  2500. "      float devf (void) volatile const { return f; }"
  2501. "  };"
  2502. ""
  2503. "void i (void)"
  2504. "{"
  2505. "  clase4 c = { 2, 3.4 };"
  2506. "  cout << c.devd () << ' ' << c.devf () << '\n'; // imprime «2 3.4»"
  2507. "}"
  2508. ""
  2509. "void main (void)"
  2510. "{"
  2511. "  f ();"
  2512. "  g ();"
  2513. "  h ();"
  2514. "  i ();"
  2515. "}"
  2516. ""
  2517. endvis
  2518. end lección 4
  2519.  
  2520. ; LECCION 5
  2521. begin
  2522. beginv
  2523. borde 2
  2524. color 1 7
  2525. centrar_coordenadas
  2526. cabecera " CONVERSIONES Y SOBRECARGA DE OPERADORES "
  2527. ""
  2528. "  ~                                                    ~  "
  2529. "  ~  En esta lección se estudia todo lo referente      ~"
  2530. "  ~  a las conversiones de tipos (tanto explícitas     ~"
  2531. "  ~  como implícitas) y la sobrecarga de operadores    ~"
  2532. "  ~  (los operadores sobrecargados son una forma       ~"
  2533. "  ~  corta de invocar a las funciones de operadores).  ~"
  2534. "  ~                                                    ~"
  2535. ""
  2536. endv
  2537. beginv
  2538. centrar_coordenadas
  2539. cabecera " INDICE DE ESTA LECCION "
  2540. ""
  2541. " En esta lección se va a estudiar los siguientes puntos:"
  2542. ""
  2543. " - ~Conversiones tradicionales:~ notación molde y conversiones implícitas. "
  2544. " - ~Conversiones de TAD's:~ notación funcional y conversiones implícitas."
  2545. " - ~Algoritmo de selección de función sobrecargada:~ tres reglas."
  2546. " - ~Especificador friend:~ hace funciones y clases amigas de una clase."
  2547. " - ~Sobrecarga de operadores:~ palabra clave operator."
  2548. " - ~Objetos grandes:~ pasarlos por referencia en los argumentos."
  2549. " - ~Asignación e inicialización:~ dos conceptos diferentes."
  2550. " - ~Ejemplo de sobrecarga de algunos operadores:~ (), [], ,, new y delete."
  2551. ""
  2552. endv
  2553. borrar_pantalla
  2554. beginv
  2555. cabecera " CONVERSIONES TRADICIONALES "
  2556. centrar_coordenadas_x 2
  2557. color 15 4
  2558. borde 2
  2559. "Las conversiones tradicionales del C++ son las conversiones de tipo que"
  2560. "realiza el C, y que por lo tanto, también las realiza el C++."
  2561. ""
  2562. "Las reglas generales de conversión son las siguientes:"
  2563. ""
  2564. "~╒══════════════════════════════════════════════════════════════════════════╕~"
  2565. "~│  Conversión automática en una expresión aritmética        x op y         │~"
  2566. "~╞══════════════════════════════════════════════════════════════════════════╡~"
  2567. "~│                                                                          │~"
  2568. "~│  Primero:                                                                │~"
  2569. "~│    Todo char y short son convertidos a int.                              │~"
  2570. "~│    Todo unsigned char y unsigned short son convertidos a unsigned.       │~"
  2571. "~│                                                                          │~"
  2572. "~│  Segundo:                                                                │~"
  2573. "~│    Si después del primer paso, los dos operandos de la expresión son de  │~"
  2574. "~│    tipo diferente, entonces de acuerdo a la jerarquía de tipos           │~"
  2575. "~│      int < unsigned < long < unsigned long < float < double              │~"
  2576. "~│    el operando de tipo más bajo es convertido al tipo del operando de    │~"
  2577. "~│    tipo más alto y el valor de la expresión es de ese tipo.              │~"
  2578. "~│                                                                          │~"
  2579. "~└──────────────────────────────────────────────────────────────────────────┘~"
  2580. endv
  2581. beginv
  2582. cabecera " EJEMPLOS DE CONVERSIONES "
  2583. centrar_coordenadas_x 3
  2584. color 1 3
  2585. borde 1
  2586. no_sombra
  2587. "char c; short s; unsigned u; int i; long l; float f; double d;"
  2588. "     Expresión     Tipo             Expresión     Tipo"
  2589. "     -----------   -------          -----------   --------"
  2590. "     c - s / i     int              u * 3 - i     unsigned"
  2591. "     u * 3.0 - i   double           f * 3 - i     float"
  2592. "     c + 1         int              3 * s * l     long"
  2593. "     c + 1.0       double           d + s         double"
  2594. endv
  2595. borrar_pantalla
  2596. beginv
  2597. cabecera " CONVERSIONES DE TAD "
  2598. centrar_coordenadas_x 2
  2599. color 14 4
  2600. borde 2
  2601. "~El C++ introduce la notación funcional para hacer conversiones explícitas de~"
  2602. "~tipo.                                                                       ~"
  2603. ""
  2604. "Una notación funcional de la forma"
  2605. ""
  2606. "  nombre_tipo (expresion)"
  2607. ""
  2608. "es equivalente a la notación molde"
  2609. ""
  2610. "  (nombre_tipo) (expresion)"
  2611. ""
  2612. "Así, estas dos expresiones son equivalentes:"
  2613. ""
  2614. "  x = float (i);"
  2615. "  x = (float) i;"
  2616. ""
  2617. "En C++ es preferible utilizar la notación funcional."
  2618. ""
  2619. "~Un constructor con un argumento es de hecho una conversión de tipo del tipo ~"
  2620. "~del argumento al tipo de la clase del constructor.                          ~"
  2621. endv
  2622. beginvis
  2623. no_multiatributo
  2624. cabecera " EJEMPLO "
  2625. coordenadas_completas 3 6 78 19
  2626. color 1 3
  2627. borde 1
  2628. no_sombra
  2629. "// Ejemplo de conversión de un tipo ya definido a un tipo definido"
  2630. "// por el usuario."
  2631. ""
  2632. "#include <iostream.h>"
  2633. ""
  2634. "class clase"
  2635. "  {"
  2636. "    int x;"
  2637. ""
  2638. "    public:"
  2639. "      clase (void) { x = 0; }"
  2640. "      clase (int i) { x = i; }"
  2641. "      int devx (void) { return x; }"
  2642. "      void imprx (void) { cout << devx () << '\n'; }"
  2643. "  };"
  2644. ""
  2645. "void main (void)"
  2646. "{"
  2647. "  clase c1;"
  2648. "  clase c2 (1);"
  2649. "  clase c3 = clase (2); // conversión de tipo explícita"
  2650. "  clase c4 = 3; // conversión de tipo implícita: clase c4 = clase (3);"
  2651. "  clase c5 = c4; // no hay conversión de tipo"
  2652. ""
  2653. "  c1.imprx (); // imprime «0»"
  2654. "  c2.imprx (); // imprime «1»"
  2655. "  c3.imprx (); // imprime «2»"
  2656. "  c4.imprx (); // imprime «3»"
  2657. "  c5.imprx (); // imprime «3»"
  2658. "}"
  2659. endvis
  2660. beginv
  2661. coordenadas_completas 3 6 78 19
  2662. color 14 4
  2663. borde 2
  2664. no_sombra
  2665. ""
  2666. ""
  2667. "   ~También es posible hacer conversiones de un tipo definido por el ~"
  2668. "   ~usuario a un tipo definido ya.                                   ~"
  2669. ""
  2670. ""
  2671. "   La forma de hacer esto es incluir funciones miembros de la forma:"
  2672. ""
  2673. "     operator tipo () { ... }"
  2674. endv
  2675. beginvis
  2676. no_multiatributo
  2677. cabecera " EJEMPLO "
  2678. coordenadas_completas 3 6 78 19
  2679. color 1 3
  2680. borde 1
  2681. no_sombra
  2682. "// Ejemplo de conversión de un tipo definido por el usuario a un"
  2683. "// tipo definido ya"
  2684. ""
  2685. "#include <iostream.h>"
  2686. ""
  2687. "class clase"
  2688. "  {"
  2689. "    int x;"
  2690. ""
  2691. "    public:"
  2692. "      clase (int i) { x = i; }"
  2693. "      operator int () { return x; }"
  2694. "  };"
  2695. ""
  2696. "inline void impr (int ent) { cout << ent << '\n'; }"
  2697. ""
  2698. "void main (void)"
  2699. "{"
  2700. "  clase c1 = clase (2); // conversión de tipo explícita"
  2701. "  clase c2 = 3; // conversión de tipo implícita: clase c4 = clase (3);"
  2702. "  clase c3 = c1; // no hay conversión de tipo"
  2703. ""
  2704. "  int a = 1;         // no hay conversión de tipo"
  2705. "  int b = int ('a'); // conversión de tipo explícita"
  2706. "  int c = 'A';       // conversión de tipo implícita: int c = int ('A');"
  2707. "  int d = int (c2);  // conversión de tipo explícita"
  2708. "  int e = c3;        // conversión de tipo implícita: int e = int (c3)"
  2709. "  int f = int (clase (4)); // dos conversiones de tipo explícita"
  2710. ""
  2711. "  impr (a); // imprime «1»"
  2712. "  impr (b); // imprime «97». Nota: el valor ASCII de 'a' es 97."
  2713. "  impr (c); // imprime «65». Nota: el valor ASCII de 'A' es 65."
  2714. "  impr (d); // imprime «3»"
  2715. "  impr (e); // imprime «2»"
  2716. "  impr (f); // imprime «4»"
  2717. "}"
  2718. endvis
  2719. borrar_pantalla
  2720. beginv
  2721. cabecera " ALGORITMO DE SELECCION DE FUNCION SOBRECARGADA "
  2722. centrar_coordenadas_x 2
  2723. color 15 4
  2724. borde 2
  2725. ""
  2726. "  ~1. Usa un ajuste exacto si se encuentra.                                ~  "
  2727. "  ~   Un short, un char, o una constante 0 es un ajuste exacto para int.   ~"
  2728. "  ~   Un float es un ajuste exacto para double.                            ~"
  2729. ""
  2730. "  ~2. Intenta conversiones implícitas de tipos estándares y usa cualquier  ~"
  2731. "  ~   ajuste.                                                              ~"
  2732. "  ~   Estas conversiones no deben perder información.                      ~"
  2733. "  ~   Dichas conversiones incluyen conversiones de puntero y las siguientes~"
  2734. "  ~   extensiones: int a long y int a double.                              ~"
  2735. ""
  2736. "  ~3. Intenta conversiones definidas por el usuario y usa un ajuste para el~"
  2737. "  ~   cual hay un único conjunto de conversiones.                          ~"
  2738. ""
  2739. endv
  2740. beginvis
  2741. no_multiatributo
  2742. cabecera " EJEMPLO "
  2743. coordenadas_completas 3 3 78 24
  2744. color 1 3
  2745. borde 1
  2746. no_sombra
  2747. "// Ejemplo de conversiones de tipos y de selección de funciones"
  2748. "// sobrecargadas"
  2749. ""
  2750. "#include <iostream.h>"
  2751. ""
  2752. "class clase"
  2753. "  {"
  2754. "    int x;"
  2755. ""
  2756. "    public:"
  2757. "      clase (int i = 0) { x = i; }"
  2758. "      operator int () { return x; }"
  2759. "  };"
  2760. ""
  2761. "inline void impr (int ent) { cout << ent << '\n'; }"
  2762. ""
  2763. "inline int max (int a, int b) { return a > b ? a : b; }"
  2764. ""
  2765. "// conversión implícita: { return int (a) > int (b) ? a : b; }"
  2766. "inline clase max (clase a, clase b) { return a > b ? a : b; }"
  2767. ""
  2768. "void main (void)"
  2769. "{"
  2770. "  clase c1 = 2;         // conversión implícita: clase c1 = clase (2);"
  2771. "  clase c2 = clase (3); // conversión explícita"
  2772. ""
  2773. "  impr (max (4, 3));   // imprime «4»"
  2774. ""
  2775. "  // conversión explícita"
  2776. "  impr (int (max (c1, c2))); // imprime «3»."
  2777. ""
  2778. "  // conversión implícita: impr (int (max (c1, c2)));"
  2779. "  impr (max (c1, c2)); // imprime «3»."
  2780. ""
  2781. "  // conversión explícita en max"
  2782. "  impr (max (int (c1), 10)); // imprime «10»."
  2783. ""
  2784. "  // conversión explícita en max"
  2785. "  impr (max (c1, clase (10))); // imprime «10»."
  2786. ""
  2787. "/*"
  2788. "  impr (max (c1, 10));"
  2789. ""
  2790. "  Esta sentencia provoca el error de compilación:"
  2791. "  "Ambigüedad entre max(clase,clase) y max(int,int).""
  2792. ""
  2793. "  Se viola la tercera regla de las tres que acabamos de mencionar ya"
  2794. "  que el compilador no sabe qué función escoger entre max(clase,clase)"
  2795. "  y max(int,int) para realizar la conversión de tipos."
  2796. "*/"
  2797. ""
  2798. "  // conversión implícita: impr (int (max (c1, c2)) + int (max (5, 6)));"
  2799. "  impr (max (c1, c2) + max (5, 6)); // imprime «9»"
  2800. ""
  2801. "  // conversión implícita: int (c2)."
  2802. "  // La conversión explícita int (2) es redundante."
  2803. "  impr (int (2) + 3 * c2); // imprime «11»"
  2804. ""
  2805. "  // conversiones implícitas: impr (int (c1 = clase (int (c2) + 2)));"
  2806. "  impr (c1 = c2 + 2); // imprime «5»"
  2807. "}"
  2808. endvis
  2809. borrar_pantalla
  2810. beginv
  2811. cabecera " ESPECIFICADOR friend "
  2812. centrar_coordenadas_x 2
  2813. color 14 4
  2814. borde 2
  2815. "La palabra clave friend (amigo/a) es un especificador de función o de clase."
  2816. "~El especificador friend permite que una función no miembro de una clase X, u~"
  2817. "~otra clase Y, puedan acceder a los miembros privados de la clase X.         ~"
  2818. endv
  2819. beginv
  2820. centrar_coordenadas_x 7
  2821. color 15 4
  2822. no_sombra
  2823. cabecera " FUNCION friend "
  2824. "La declaración de la función amiga debe aparecer en el interior de la"
  2825. "definición de la clase. La declaración de la función amiga debe empezar"
  2826. "con la palabra clave friend. Esta declaración puede aparecer en la parte"
  2827. "pública o en la parte privada de la clase sin afectar a su significado."
  2828. endv
  2829. beginvis
  2830. no_multiatributo
  2831. cabecera " EJEMPLO "
  2832. color 1 3
  2833. borde 1
  2834. coordenadas_completas 2 3 78 23
  2835. "// Ejemplo de función friend"
  2836. ""
  2837. "#include <iostream.h>"
  2838. ""
  2839. "class clase"
  2840. "  {"
  2841. "    friend void asig (clase& cl, int i);"
  2842. "    friend int dev (clase cl) { return cl.x; }"
  2843. ""
  2844. "    int x;"
  2845. ""
  2846. "    public:"
  2847. "      clase (int i = 0) { x = i; }"
  2848. "      int devx (void) { return x; }"
  2849. "  };"
  2850. ""
  2851. "inline void asig (clase& cl, int i) { cl.x = i; }"
  2852. ""
  2853. "void main (void)"
  2854. "{"
  2855. "  clase c (5);"
  2856. "  cout << dev (c) << '\n'; // imprime «5»"
  2857. "  asig (c, -2);"
  2858. "  cout << c.devx () << '\n'; // imprime «-2»"
  2859. "}"
  2860. endvis
  2861. beginv
  2862. centrar_coordenadas_x 13
  2863. color 15 4
  2864. no_sombra
  2865. cabecera " FUNCION MIEMBRO friend "
  2866. "Las funciones miembros de una clase Y pueden ser funciones amigas de otra "
  2867. "clase X. En este caso es necesario utilizar el operador de resolución de"
  2868. "ámbito en la declaración de la función amiga dentro de la clase X."
  2869. endv
  2870. beginvis
  2871. no_multiatributo
  2872. cabecera " EJEMPLO "
  2873. color 1 3
  2874. borde 1
  2875. coordenadas_completas 2 3 78 23
  2876. "// Ejemplo de función miembro friend"
  2877. ""
  2878. "#include <iostream.h>"
  2879. ""
  2880. "class clase_B; // declarac. (no definic.) para que sea conocida en clase_A"
  2881. ""
  2882. "class clase_A"
  2883. "  {"
  2884. "    public:"
  2885. "      int dev (clase_B cl);"
  2886. "  };"
  2887. ""
  2888. "class clase_B"
  2889. "  {"
  2890. "    friend int clase_A::dev (clase_B cl);"
  2891. ""
  2892. "    int x;"
  2893. ""
  2894. "    public:"
  2895. "      clase_B (int i = 0) { x = i; }"
  2896. "      int devx (void) { return x; }"
  2897. "  };"
  2898. ""
  2899. "inline int clase_A::dev (clase_B cl) { return cl.x; }"
  2900. ""
  2901. "void main (void)"
  2902. "{"
  2903. "  clase_B c1 (5);"
  2904. "  clase_A c2;"
  2905. "  cout << c1.devx () << '\n'; // imprime «5»"
  2906. "  cout << c2.dev (c1) << '\n'; // imprime «5»"
  2907. "}"
  2908. endvis
  2909. beginv
  2910. centrar_coordenadas_x 18
  2911. color 15 4
  2912. no_sombra
  2913. cabecera " CLASE friend "
  2914. "Si todas las funciones miembros de una clase son funciones amigas de otra "
  2915. "clase, se dice que una clase es amiga (friend) de otra. La declaración es"
  2916. "  friend class nombre_de_clase"
  2917. "en lugar de"
  2918. "  friend declaracion_de_funcion"
  2919. endv
  2920. beginvis
  2921. no_multiatributo
  2922. cabecera " EJEMPLO "
  2923. color 1 3
  2924. borde 1
  2925. coordenadas_completas 2 3 78 23
  2926. "// Ejemplo de clase friend"
  2927. ""
  2928. "#include <iostream.h>"
  2929. ""
  2930. "class clase_B; // declarac. (no definic.) para que sea conocida en clase_A"
  2931. ""
  2932. "class clase_A"
  2933. "  {"
  2934. "    friend clase_B;"
  2935. ""
  2936. "    int x;"
  2937. ""
  2938. "    public:"
  2939. "      clase_A (int i = 0) { x = i; }"
  2940. "      int devx (void) { return x; }"
  2941. "  };"
  2942. ""
  2943. "class clase_B"
  2944. "  {"
  2945. "    public:"
  2946. "      int dev (clase_A cl) { return cl.x; }"
  2947. "  };"
  2948. ""
  2949. "void main (void)"
  2950. "{"
  2951. "  clase_A c1 (5);"
  2952. "  clase_B c2;"
  2953. "  cout << c1.devx () << '\n'; // imprime «5»"
  2954. "  cout << c2.dev (c1) << '\n'; // imprime «5»"
  2955. "}"
  2956. endvis
  2957. borrar_pantalla
  2958. partir
  2959. beginv
  2960. cabecera " SOBRECARGA DE OPERADORES "
  2961. centrar_coordenadas_x 2
  2962. color 15 4
  2963. borde 2
  2964. "Los operadores se pueden sobrecargar al igual que las funciones. La uti-"
  2965. "lización de operadores sobrecargados conduce a programas más cortos y más"
  2966. "legibles."
  2967. endv
  2968. beginv
  2969. centrar_coordenadas_x 3
  2970. color 4 7
  2971. "Hemos utilizado anteriormente la palabra clave ~operator~ para definir una "
  2972. "función miembro que realiza la conversión de tipos. También puede usarse"
  2973. "esta palabra clave para sobrecargar operadores de C++."
  2974. endv
  2975. beginvis
  2976. no_multiatributo
  2977. coordenadas_completas 1 8 80 24
  2978. color 14 4
  2979. borde 2
  2980. "Aunque se sumen nuevos significados a los operadores, su asociatividad y"
  2981. "precedencia se conserva. Tampoco se puede cambiar la sintaxis de operadores,"
  2982. "por ejemplo, no es posible definir un operador unario % o uno binario !."
  2983. ""
  2984. "Los operadores que no pueden ser sobrecargados son:"
  2985. "  - operador de selector de componente (.)"
  2986. "  - operador de referencia a través de un puntero a un miembro (.*)"
  2987. "  - operador de resolución/acceso de ámbito (::)"
  2988. "  - operador condicional (?:)"
  2989. ""
  2990. "Los operadores de autoincremento y autodecremento, ++ y --, se pueden sobre-"
  2991. "cargar pero sus significados en notación prefija y postfija es el mismo en"
  2992. "la forma sobrecargada."
  2993. ""
  2994. "Todos los demás operadores se pueden sobrecargar, éstos incluyen:"
  2995. "  - operadores aritméticos        - operadores de bits"
  2996. "  - operadores lógicos            - operador de indexado []"
  2997. "  - operadores de comparación     - llamada a función ()"
  2998. "  - operadores de igualdad        - operadores new y delete"
  2999. "  - operadores de asignación"
  3000. ""
  3001. "No es posible definir nuevos tokens de operadores, pero se puede usar la"
  3002. "notación de llamada a función cuando este conjunto de operadores es ina-"
  3003. "decuado. Por ejemplo, usa pow() en vez de **."
  3004. ""
  3005. "El ; no se puede sobrecargar puesto que no es un operador."
  3006. endvis
  3007. beginv
  3008. cabecera " FUNCION OPERADOR (operator) "
  3009. coordenadas_completas 1 8 80 24
  3010. color 15 6
  3011. ""
  3012. " ~El nombre de una función operador es la palabra clave operator seguida por~"
  3013. " ~el operador.~ Por ejemplo, operator<<. Una función operador es declarada"
  3014. " como cualquier otra función y por lo tanto puede ser llamada como cualquier"
  3015. " otra; el uso del operador es solamente una forma corta de escribir una"
  3016. " llamada explícita de una función de operador. Por ejemplo, definida una"
  3017. " clase complex en la cual se ha definido un operador de suma, las dos ini-"
  3018. " cializaciones siguientes son sinónimas."
  3019. ""
  3020. "   void f (complex a, complex b)"
  3021. "   {"
  3022. "     complex c = a + b;            // forma corta"
  3023. "     complex d = operator+ (a, b), // llamada explícita"
  3024. "   }"
  3025. endv
  3026. beginv
  3027. cabecera " OPERADORES BINARIOS Y UNARIOS "
  3028. centrar_coordenadas_x 8
  3029. color 15 5
  3030. borde 2
  3031. "~Hay dos formas de sobrecargar los operadores: haciendo que sean funciones~"
  3032. "~miembros o haciendo que sean funciones amigas.~"
  3033. ""
  3034. "Un operador binario puede ser definido bien usando una función que toma"
  3035. "un argumento o bien usando una función amiga que toma dos argumentos."
  3036. "Así, para cualquier operador binario @, a@b puede ser interpretado bien"
  3037. "como a.operator@(b) o bien como operator@(a,b). Si ambos están definidos,"
  3038. "a@b es un error."
  3039. ""
  3040. "Un operador unario, ya sea prefijo o postfijo, puede ser definido bien"
  3041. "usando una función miembro que no toma ningún argumento o bien usando"
  3042. "una función amiga que toma un argumento. Así, para cualquier operador @,"
  3043. "tanto a@ como @a puede ser interpretado bien como a.operator@() o bien"
  3044. "como operator@(a). Si ambos están definidos, a@ y @a son errores."
  3045. endv
  3046. beginv
  3047. centrar_coordenadas_x 7
  3048. color 14 6
  3049. "Considerar este ejemplo:"
  3050. ""
  3051. "  class X"
  3052. "    {"
  3053. "      // funciones amigas:"
  3054. "      friend X operator- (X);     // menos unario"
  3055. "      friend X operator- (X,X);   // menos binario"
  3056. "      friend X operator- ();      // error: no hay operando"
  3057. "      friend X operator- (X,X,X); // error: ternario"
  3058. ""
  3059. "      // funciones miembros (con primer argumento implícita: this):"
  3060. "      X *operator& ();   // unario & (dirección de)"
  3061. "      X operator& (X);   // binario & (and a nivel de bits)"
  3062. "      X operator& (X,X); // error: ternario"
  3063. "    };"
  3064. endv
  3065. beginvis
  3066. no_multiatributo
  3067. cabecera " EJEMPLO "
  3068. coordenadas_completas 3 3 78 23
  3069. color 1 3
  3070. borde 1
  3071. "// Ejemplo de operadores sobrecargados."
  3072. ""
  3073. "#include <iostream.h>"
  3074. ""
  3075. "class clase"
  3076. "  {"
  3077. "    friend clase operator- (clase c1, clase c2);"
  3078. "    friend clase operator- (clase cl) { return 0 - cl; }"
  3079. "    friend clase operator/ (clase, clase);"
  3080. ""
  3081. "    private:"
  3082. ""
  3083. "    int x, y;"
  3084. ""
  3085. "    public:"
  3086. ""
  3087. "    clase (int xx = 0, int yy = 0) { x = xx; y = yy; }"
  3088. "    int getx (void) { return x; }"
  3089. "    int gety (void) { return y; }"
  3090. "    clase operator+ (clase cl) { return *this - -cl; }"
  3091. "    clase operator+ (void) { return *this; }"
  3092. "    clase operator* (clase);"
  3093. "  };"
  3094. ""
  3095. "inline clase operator- (clase c1, clase c2)"
  3096. "{"
  3097. "  return clase (c1.getx () - c2.getx (), c1.gety () - c2.gety ());"
  3098. "}"
  3099. ""
  3100. "inline clase operator/ (clase c1, clase c2)"
  3101. "{"
  3102. "  return clase (c1.getx () / c2.getx (), c1.gety () / c2.gety ());"
  3103. "}"
  3104. ""
  3105. "inline clase clase::operator* (clase cl)"
  3106. "{"
  3107. "  return clase (this->getx () * cl.getx (), this->gety () * cl.gety ());"
  3108. "}"
  3109. ""
  3110. "inline void escribir (clase c)"
  3111. "{"
  3112. "  cout << c.getx () << ' ' << c.gety () << '\n';"
  3113. "}"
  3114. ""
  3115. "void main (void)"
  3116. "{"
  3117. "  clase c1 (5), c2 (2, 3);"
  3118. ""
  3119. "  escribir (c1 - c2);           // imprime «-3 -3»"
  3120. "  escribir (c1 + c2);           // imprime «7 3»"
  3121. "  escribir (-c1 - +c2);         // imprime «-7 -3»"
  3122. "  escribir (c1 / c2 + c2 * c1); // imprime «12 0»"
  3123. ""
  3124. "  clase c3 = c1 + c2 + c2;"
  3125. "  escribir (c3 * c3);           // imprime «81 36»"
  3126. "}"
  3127. endvis
  3128. beginv
  3129. cabecera " SIGNIFICADOS PREDEFINIDOS PARA LOS OPERADORES "
  3130. coordenadas_completas 1 2 80 24
  3131. color 15 1
  3132. borde 2
  3133. "~No se hace ninguna asunción acerca del significado de un operador definido~"
  3134. "~por el usuario.~ En particular, puesto que un = sobrecargado no se asume para"
  3135. "implementar la asignación del segundo operando al primer operando, no se"
  3136. "testea para asegurar que el primer operando es un lvalue (un lvalue es una"
  3137. "dirección que aparece en el lado izquierdo de una sentencia de asignación y"
  3138. "a la cual se le puede dar un valor). El significado de algunos operadores ya"
  3139. "construidos están definidos para ser equivalentes a alguna combinación de"
  3140. "otros operadores sobre los mismos argumentos. Por ejemplo, si a es un int,"
  3141. "++a significa a+=1, y esto significa a su vez a=a+1. En los operadores defi-"
  3142. "nidos por el usuario tales equivalencias no son ciertas (a no ser que el"
  3143. "usuario defina estos operadores de esa forma). ~Los operadores = y & tienen~"
  3144. "~significados predefinidos cuando se aplican a objetos de clases.~ No hay una"
  3145. "forma elegante de "indefinir" estos dos operadores. Puede ser, sin embargo,"
  3146. "inhabilitados para una clase X. Se puede declarar, por ejemplo, X::operator&"
  3147. "() sin proporcionar una definición para él. Si en algún lugar se toma la"
  3148. "dirección de un objeto de la clase X, el enlazador detectará la ausencia de"
  3149. "la definición. En algunos sistemas esta técnica no puede ser usada porque el"
  3150. "enlazador es tan "inteligente" que detecta que hay una función declarada y"
  3151. "no definida aun cuando tal función no se use. Por ello, una solución alter-"
  3152. "nativa es definir la función X::operator&() para que provoque un error en"
  3153. "tiempo de ejecución."
  3154. endv
  3155. beginvis
  3156. no_multiatributo
  3157. no_posicion
  3158. cabecera " UNA CLASE DE NUMEROS COMPLEJOS (clase complex) "
  3159. coordenadas_completas 7 4 73 21
  3160. color 15 2
  3161. borde 2
  3162. "Las funciones de operadores, al igual que todas las funciones,"
  3163. "se pueden sobrecargar. Por ejemplo:"
  3164. ""
  3165. "  class complex"
  3166. "    {"
  3167. "      double re, im;"
  3168. ""
  3169. "      public:"
  3170. ""
  3171. "      complex (double r, double i) { re = r; im = i; }"
  3172. ""
  3173. "      friend complex operator+ (complex, complex);"
  3174. "      friend complex operator+ (complex, double);"
  3175. "      friend complex operator+ (double, complex);"
  3176. ""
  3177. "      friend complex operator- (complex, complex);"
  3178. "      friend complex operator- (complex, double);"
  3179. "      friend complex operator- (double, complex);"
  3180. "      complex operator- ();"
  3181. ""
  3182. "      friend complex operator* (complex, complex);"
  3183. "      friend complex operator* (complex, double);"
  3184. "      friend complex operator* (double, complex);"
  3185. ""
  3186. "      // ..."
  3187. "    };"
  3188. ""
  3189. "  void f (void)"
  3190. "  {"
  3191. "    complex a (1, 1), b (2, 2), c (3, 3), d (4, 4), e (5, 5);"
  3192. "    a = -b - c;"
  3193. "    b = c * 2.0 * c;"
  3194. "    c = (d + e) * a;"
  3195. "  }"
  3196. ""
  3197. "Para evitar escribir tres funciones sobrecargadas para cada"
  3198. "operador binario, declaramos un constructor que, dado un double"
  3199. "cree un complex. Por ejemplo:"
  3200. ""
  3201. "  class complex"
  3202. "    {"
  3203. "      // ..."
  3204. ""
  3205. "      complex (double r) { re = r; im = 0; }"
  3206. "    };"
  3207. ""
  3208. "Ahora podemos hacer:"
  3209. ""
  3210. "  complex z1 = complex (23);"
  3211. "  complex z2 = 23;"
  3212. ""
  3213. "donde, tanto z1 como z2, serán inicializados llamando a"
  3214. "complex(23,0)."
  3215. ""
  3216. "La clase complex la podemos declarar de esta nueva forma:"
  3217. ""
  3218. "  class complex"
  3219. "   {"
  3220. "     double re, im;"
  3221. ""
  3222. "     public:"
  3223. ""
  3224. "     complex (double r, double i = 0) { re = r; im = i; }"
  3225. ""
  3226. "     friend complex operator+ (complex, complex);"
  3227. "     friend complex operator* (complex, complex);"
  3228. "   };"
  3229. ""
  3230. "y deberían ser legales las operaciones que involucren variables"
  3231. "complex y constantes enteras. Una constante entera será inter-"
  3232. "pretada como complex con la parte imaginaria cero. Por ejemplo,"
  3233. ""
  3234. "  a = b * 2"
  3235. ""
  3236. "significa"
  3237. ""
  3238. "  a = operator+ (b, complex (double (2), double (0)))"
  3239. ""
  3240. "Una conversión definida por el usuario es aplicada implícita-"
  3241. "mente únicamente si es única."
  3242. ""
  3243. "Un objeto construido por el uso explícito o implícito de un"
  3244. "constructor es automático y será destruido en la primera opor-"
  3245. "tunidad, normalmente inmediatamente después de la sentencia en"
  3246. "la cual fue creado."
  3247. endvis
  3248. beginv
  3249. centrar_coordenadas
  3250. cabecera " OPERADORES # Y ## DEL PREPROCESADOR "
  3251. color 15 7
  3252. ""
  3253. "No se pueden sobrecargar los operadores # y ## porque son operadores del"
  3254. "preprocesador de C++, no del lenguaje C++. Los operadores almohadilla (#)"
  3255. "y doble almohadilla (##) ejecutan sustituciones y fusionado de tokens en"
  3256. "la fase de exploración del preprocesador."
  3257. ""
  3258. "El operador unario # convierte (sustituye) el token de su operando en"
  3259. "string. El operador binario ## fusiona dos tokens (operando izquierdo"
  3260. "y operando derecho en un sólo token."
  3261. ""
  3262. "El símbolo # también se utiliza para indicar una directiva del prepro-"
  3263. "cesador, pero en este caso no actúa como operador."
  3264. ""
  3265. "El siguiente ejemplo muestra cómo se utilizan los operadores # y ## del"
  3266. "preprocesador."
  3267. ""
  3268. endv
  3269. beginvis
  3270. no_multiatributo
  3271. cabecera " EJEMPLO "
  3272. coordenadas_completas 3 4 77 22
  3273. color 1 3
  3274. borde 1
  3275. "// Ejemplo de los operadores # y ## del preprocesador de C++."
  3276. ""
  3277. "#include <iostream.h>"
  3278. ""
  3279. "#define impr_suma(x)  cout << #x " + " #x " = " << x + x << "\n""
  3280. "#define var(x,y) (x##y)"
  3281. ""
  3282. "void main (void)"
  3283. "{"
  3284. "  int x1;"
  3285. "  var (x, 1) = 5;"
  3286. "  cout << "Ejemplo" " de los " "operadores # y ## del "
  3287. "          "preprocesador:\n";"
  3288. "  impr_suma (x1);"
  3289. "  impr_suma (100);"
  3290. "}"
  3291. ""
  3292. "/*"
  3293. "SALIDA DEL PROGRAMA:"
  3294. ""
  3295. "Ejemplo de los operadores # y ## del preprocesador:"
  3296. "x1 + x1 = 10"
  3297. "100 + 100 = 200"
  3298. "*/"
  3299. endvis
  3300. borrar_pantalla
  3301. beginv
  3302. cabecera " OBJETOS GRANDES "
  3303. centrar_coordenadas
  3304. borde 2
  3305. color 11 1
  3306. ""
  3307. "  Cuando se pasa un objeto como ~argumento por valor~ a una  "
  3308. "  función, se está pasando, en realidad, una copia de ese"
  3309. "  objeto. En objetos de cierto tamaño es deseable evitar"
  3310. "  tanto traspaso de información. Esto se consigue pasando"
  3311. "  los objetos como ~argumento por referencia~ a las funcio-"
  3312. "  nes. Para ello utilizamos el operador de referencia ~&~."
  3313. ""
  3314. endv
  3315. borrar_pantalla
  3316. beginv
  3317. cabecera " ASIGNACION E INICIALIZACION "
  3318. color 0 7
  3319. centrar_coordenadas_x 2
  3320. "Consideremos una clase string muy simple:"
  3321. ""
  3322. "  struct string"
  3323. "    {"
  3324. "      char *p;"
  3325. "      int size; // tamaño del vector apuntado por p"
  3326. ""
  3327. "      string (int sz) { p = new char[size = sz]; }"
  3328. "      ~~string () { delete p; }"
  3329. "    };"
  3330. endv
  3331. beginv
  3332. centrar_coordenadas_x 3
  3333. "Un string es una estructura de datos compuesta de un puntero a un vector"
  3334. "de caracteres y el tamaño de ese vector. El vector es creado por el cons-"
  3335. "tructor y borrado por el destructor. Sin embargo, tal y como está cons-"
  3336. "truida la clase string puede causar problemas. Por ejemplo:"
  3337. ""
  3338. "  void f (void)"
  3339. "  {"
  3340. "    string s1 (10);"
  3341. "    string s2 (20);"
  3342. "    s1 = s2;"
  3343. "  }"
  3344. ""
  3345. "asignará dos vectores de caracteres, pero la asignación s1 = s2 hará que"
  3346. "el puntero p de s1 apunte al mismo sitio que el puntero p de s2. Cuando"
  3347. "sean invocados los destructores s1 y s2, se destruirá dos veces el mismo"
  3348. "vector con resultados desastrosos impredecibles. La solución a este pro-"
  3349. "blema es definir apropiadamente la asignación de los objetos string."
  3350. endv
  3351. beginv
  3352. centrar_coordenadas_x 3
  3353. no_sombra
  3354. "La asignación por defecto entre objetos es la copia de elementos"
  3355. "de uno a otro. Definamos un nuevo operador de asignación a nuestra"
  3356. "clase string para resolver el problema planteado:"
  3357. ""
  3358. "  struct string"
  3359. "    {"
  3360. "      char *p;"
  3361. "      int size; // tamaño del vector apuntado por p"
  3362. "      string (int sz) { p = new char[size = sz]; }"
  3363. "      ~~string () { delete p; }"
  3364. "      void operator= (string&);"
  3365. "    };"
  3366. ""
  3367. "  void string::operator= (string& a)"
  3368. "  {"
  3369. "    if (this == &a) return; // previene s = s"
  3370. "    delete p;"
  3371. "    p = new char[size = a.size];"
  3372. "    strcpy (p, a.p);"
  3373. "  }"
  3374. endv
  3375. beginv
  3376. centrar_coordenadas_x 4
  3377. "Con la nueva definición de string aseguramos que el ejemplo"
  3378. "anterior (función f()) trabajará correctamente. Sin embargo,"
  3379. "todavía hay un problema latente que lo podemos observar si"
  3380. "hacemos una pequeña modificación en f():"
  3381. ""
  3382. "  void f (void)"
  3383. "  {"
  3384. "    string s1 (10);"
  3385. "    string s2 = s1;"
  3386. "  }"
  3387. ""
  3388. "Ahora sólo un string es construido pero dos son destruidos."
  3389. "Los operadores de asignación definidos por el usuario no son"
  3390. "aplicados a objetos no inicializados. Un rápido vistazo a"
  3391. "string::operator=() muestra porqué esto es así: el puntero"
  3392. "p contendría un valor indefinido (aleatorio). Consecuente-"
  3393. "mente, debemos definir otra función miembro adicional para"
  3394. "hacer frente a la inicialización."
  3395. endv
  3396. beginv
  3397. centrar_coordenadas_x 5
  3398. "La nueva definición de string para tener en cuenta la"
  3399. "inicialización es:"
  3400. ""
  3401. "  struct string"
  3402. "    {"
  3403. "      char *p;"
  3404. "      int size; // tamaño del vector apuntado por p"
  3405. "      string (int sz) { p = new char[size = sz]; }"
  3406. "      ~~string () { delete p; }"
  3407. "      void operator= (string&);"
  3408. "    };"
  3409. ""
  3410. "  void string::string (string& a)"
  3411. "  {"
  3412. "    p = new char[size = a.size];"
  3413. "    strcpy (p, a.p);"
  3414. "  }"
  3415. endv
  3416. beginv
  3417. centrar_coordenadas_x 6
  3418. "Para un tipo X, el constructor X(X&) proporciona la inicialización para un"
  3419. "objeto del mismo tipo X. Las operaciones de asignación y de inicialización"
  3420. "son diferentes; pero sólo tiene especial importancia tal diferencia cuando"
  3421. "una clase X tiene un destructor que realiza tareas no triviales, tales co-"
  3422. "mo desasignación de memoria, en cuyo caso es deseable evitar la copia ele-"
  3423. "mento a elemento de objetos:"
  3424. ""
  3425. "  class X"
  3426. "    {"
  3427. "      // ..."
  3428. "      X (algo);       // constructor: crea objetos"
  3429. "      X (X&);         // constructor: copia en inicialización"
  3430. "      operator= (X&); // asignación: borrado y copia"
  3431. "      ~~X ();          // destructor: borrado"
  3432. "    };"
  3433. endv
  3434. beginvis
  3435. no_multiatributo
  3436. coordenadas_completas 2 3 78 23
  3437. color 0 7
  3438. borde 2
  3439. "Hay dos casos más en los que un objeto es copiado: como un argumento de"
  3440. "función y como un valor devuelto por una función. En ambos casos se crea"
  3441. "una variable que es inicializada con el objeto del argumento o con el"
  3442. "objeto a devolver; en ambos casos se llamará, por tanto, a la función"
  3443. "X(&X) si ésta está definida:"
  3444. ""
  3445. "  string g (string arg)"
  3446. "  {"
  3447. "    return arg;"
  3448. "  }"
  3449. ""
  3450. "  void main (void)"
  3451. "  {"
  3452. "    string s = "asdf";"
  3453. "    s = g (s);"
  3454. "  }"
  3455. ""
  3456. "Claramente, el valor de s debería ser "asdf" después de la llamada a"
  3457. "g(). El argumento arg se convierte en una copia del valor de s llamando"
  3458. "a string::string(string&). El valor devuelto por g() es una copia del"
  3459. "valor de arg creada llamando a string::string(string&); esta vez, la"
  3460. "variable inicializada es una variable temporal, la cual es asignada a"
  3461. "s. Tales variables temporales son destruidas, usando string::~string(),"
  3462. "tan pronto como es posible."
  3463. endvis
  3464. beginvis
  3465. no_multiatributo
  3466. no_posicion
  3467. cabecera " EJEMPLO DE SOBRECARGA DE ALGUNOS OPERADORES "
  3468. coordenadas_completas 1 2 80 24
  3469. color 7 0
  3470. borde 2
  3471. "#include <iostream.h> // cout"
  3472. "#include <stddef.h>   // size_t"
  3473. ""
  3474. "class clase"
  3475. "  {"
  3476. "    public:"
  3477. ""
  3478. "    int x, y, sum, dif, prod;"
  3479. ""
  3480. "    clase (int i, int j): x (i), y (j), sum (i + j),"
  3481. "                          dif (i -j), prod (x * y) {}"
  3482. ""
  3483. "    void escr (const char *s)"
  3484. "    {"
  3485. "      cout << "\n" << s << ": x = " << x << " y = " << y << " sum = " << sum"
  3486. "           << " dif = " << dif << " prod = " << prod;"
  3487. "    }"
  3488. ""
  3489. "    operator int () { return dif; }"
  3490. ""
  3491. "    int operator () (void) { return prod; }"
  3492. ""
  3493. "    int operator [] (int ind)"
  3494. "      { return ind == 0 ? sum : ind == 1 ? prod : 0; }"
  3495. ""
  3496. "    // cambia prioridad de operador , para la clase"
  3497. "    clase operator, (clase) { return *this; }"
  3498. ""
  3499. "    void *operator new (size_t)"
  3500. "    {"
  3501. "      cout << "\nERROR: no se puede aplicar el operador new a un objeto ""
  3502. "              "de clase.";"
  3503. "      return 0;"
  3504. "    }"
  3505. ""
  3506. "    void operator delete (void *) { }"
  3507. "  };"
  3508. ""
  3509. "void main (void)"
  3510. "{"
  3511. "  clase cl1 (1, 2), cl2 (2, 3), cl3 (3, 4);"
  3512. "  int a = cl1, b = cl2 (), c = cl3 [1];"
  3513. ""
  3514. "  cout << "\n** Inicializando: clase cl1 (1, 2), cl2 (2, 3), cl3 (3, 4);""
  3515. "          "\n                  int a = cl1, b = cl2 (), c = cl3 [1];";"
  3516. "  cl1.escr ("cl1");"
  3517. "  cl2.escr ("cl2");"
  3518. "  cl3.escr ("cl3");"
  3519. "  cout << "\na = " << a << " b = " << b << " c = " << c;"
  3520. ""
  3521. "  a = (b, c, 5);"
  3522. "  cl1 = (cl2, cl3, clase (5, 5));"
  3523. ""
  3524. "  cout << "\n** Ejecutando: a = (b, c, 5); cl1 = (cl2, cl3, clase (5, 5));";"
  3525. "  cout << "\na = " << a;"
  3526. "  cl1.escr ("cl1");"
  3527. ""
  3528. "  cout << "\n** Ejecutando: clase *pclase = new clase;";"
  3529. "  clase *pclase = new clase (0, 0);"
  3530. "  cout << "\n** Ejecutando: delete *pclase;";"
  3531. "  delete pclase;"
  3532. ""
  3533. "  cout << "\n";"
  3534. "}"
  3535. ""
  3536. "/*"
  3537. ""
  3538. "SALIDA DE ESTE PROGRAMA:"
  3539. ""
  3540. "** Inicializando: clase cl1 (1, 2), cl2 (2, 3), cl3 (3, 4);"
  3541. "                  int a = cl1, b = cl2 (), c = cl3 [1];"
  3542. "cl1: x = 1 y = 2 sum = 3 dif = -1 prod = 2"
  3543. "cl2: x = 2 y = 3 sum = 5 dif = -1 prod = 6"
  3544. "cl3: x = 3 y = 4 sum = 7 dif = -1 prod = 12"
  3545. "a = -1 b = 6 c = 12"
  3546. "** Ejecutando: a = (b, c, 5); cl1 = (cl2, cl3, clase (5, 5));"
  3547. "a = 5"
  3548. "cl1: x = 2 y = 3 sum = 5 dif = -1 prod = 6"
  3549. "** Ejecutando: clase *pclase = new clase;"
  3550. "ERROR: no se puede aplicar el operador new a un objeto de clase."
  3551. "** Ejecutando: delete *pclase;"
  3552. ""
  3553. "*/"
  3554. endvis
  3555. end lección 5
  3556.  
  3557. ; LECCION 6
  3558. begin
  3559. beginv
  3560. borde 2
  3561. color 1 7
  3562. centrar_coordenadas
  3563. cabecera " HERENCIA SIMPLE "
  3564. no_sombra
  3565. "~Esta lección describe los conceptos de herencia y clases derivadas en ~"
  3566. "~C++. Herencia es el mecanismo de derivar una nueva clase de otra vieja~"
  3567. "~clase. Esto es, una clase puede adquirir todas las características de ~"
  3568. "~otra clase. A la nueva clase se le llama clase derivada y a la vieja  ~"
  3569. "~clase se le llama clase base. Las clases derivadas proporcionan un    ~"
  3570. "~mecanismo simple, flexible y eficiente para especificar una interface ~"
  3571. "~alternativa para una clase y para definir una clase añadiendo facili- ~"
  3572. "~dades a una clase que ya existe sin reprogramación ni recompilación.  ~"
  3573. "~La herencia es una característica importante de la programación orien-~"
  3574. "~tada a objeto.                                                        ~"
  3575. ""
  3576. "En los primeros estándares de C++, una clase derivada sólo podía here-"
  3577. "dar la descripción de una clase base (herencia simple). En los nuevos"
  3578. "estándares, una clase derivada puede tener varias clases bases (heren-"
  3579. "cia múltiple). En esta lección estudiaremos la herencia simple y en la"
  3580. "siguiente veremos la herencia múltiple."
  3581. endv
  3582. beginv
  3583. centrar_coordenadas
  3584. cabecera " INDICE DE ESTA LECCION "
  3585. ""
  3586. "****************************************************************************"
  3587. ""
  3588. "En esta lección se va a estudiar los siguientes puntos:"
  3589. ""
  3590. "- ~Clases derivadas:~ son clases que derivan de otras clases llamadas bases."
  3591. "- ~Modificadores de acceso public, private y protected:~ estudio completo."
  3592. "- ~Punteros a clases derivadas:~ clase derivada es un subtipo de clase base."
  3593. "- ~Funciones virtuales:~ funciones declaradas con el especificador virtual."
  3594. "- ~Funciones puras:~ son clases virtuales sin definición en clases bases."
  3595. "- ~Clases abstractas:~ son las clases que tienen al menos una función pura."
  3596. "- ~Jerarquía de clases:~ una clase derivada puede ser también una clase base."
  3597. ""
  3598. "****************************************************************************"
  3599. ""
  3600. endv
  3601. beginv
  3602. cabecera " CLASES DERIVADAS "
  3603. color 15 5
  3604. coordenadas_completas 1 2 80 24
  3605. "Una clase puede ser derivada de una clase existente usando la foma:"
  3606. ""
  3607. "~(class | struct) nombre_clase_derivada: [public | private] nombre_clase_base~"
  3608. "~  {                                                                         ~"
  3609. "~    declaracion_de_los_miembros                                             ~"
  3610. "~  };                                                                        ~"
  3611. ""
  3612. "donde (class | struct) quiere decir que en ese lugar debe ir obligatoria-"
  3613. "mente la palabra clave ~class~ o la palabra clave ~struct~; y [public | private]"
  3614. "quiere decir que en ese lugar puede ir opcionalmente los modificadores de"
  3615. "acceso ~public~ o ~private~. Si no aparece ninguno de los dos modificadores de"
  3616. "acceso, se considerará, por defecto, public para struct y private para class"
  3617. ""
  3618. "Por ejemplo,"
  3619. "  struct d : b { ..."
  3620. "significa"
  3621. "  class d : public b { public: ..."
  3622. "y viceversa,"
  3623. "  class b : b { ..."
  3624. "significa"
  3625. "  struct b: private b { private: ..."
  3626. endv
  3627. beginvis
  3628. no_multiatributo
  3629. color 15 5
  3630. coordenadas_completas 3 3 78 23
  3631. borde 2
  3632. no_sombra
  3633. "Ejemplo de clase derivada:"
  3634. ""
  3635. "  class empleado"
  3636. "    {"
  3637. "      public:"
  3638. "        char *nombre;"
  3639. "        short edad;"
  3640. "        short departamento;"
  3641. "        int salario;"
  3642. "        void imprimir (void);"
  3643. "    };"
  3644. ""
  3645. "  class director: public empleado"
  3646. "    {"
  3647. "      public:"
  3648. "        int num_empleados;"
  3649. "        short tipo_director;"
  3650. "    };"
  3651. ""
  3652. "La clase director es una clase derivada de la clase empleado, y por con-"
  3653. "siguiente, la clase empleado es una clase base para la clase director."
  3654. "La clase director tiene todos los miembros públicos de la clase empleado"
  3655. "(nombre, edad, etc.) que son añadidos a los dos que ya posee la clase"
  3656. "director. Por lo tanto, la clase empleado tiene cinco miembros y la clase"
  3657. "director tiene siete."
  3658. ""
  3659. "Si no utilizáramos la herencia, haríamos:"
  3660. ""
  3661. "  class director"
  3662. "    {"
  3663. "      public:"
  3664. "        empleado empl;"
  3665. "        int num_empleados;"
  3666. "        short tipo_director;"
  3667. "    };"
  3668. ""
  3669. "Esta segunda versión de la clase director no es equivalente a la primera."
  3670. "En la primera versión, la clase director tiene siete miembros, en la se-"
  3671. "gunda tiene tres, donde el miembro empl tiene a su vez cinco miembros."
  3672. "Desde el punto de vista lógico, en esta segunda versión no podemos decir"
  3673. "que un director es un empleado, sino más bien que empleado es una parte"
  3674. "de director. Hay otras diferencias como las conversiones de punteros a"
  3675. "las clases empleado y director que se explicarán más adelante."
  3676. ""
  3677. "En el ejemplo de los directores y empleados, la forma natural de imple-"
  3678. "mentarlo en C++ es utilizando la herencia puesto que un director es un"
  3679. "empleado y posee todas las características de los empleados."
  3680. endvis
  3681. beginv
  3682. cabecera " MODIFICADORES DE ACCESO public, private Y protected "
  3683. color 15 4
  3684. coordenadas_completas 1 2 80 24
  3685. "Los miembros de una clase pueden adquirir atributos de acceso de dos formas:"
  3686. "por defecto, o a través del uso de los especificadores de acceso public,"
  3687. "private y protected. La forma de utililizar estos especificadores es:"
  3688. ""
  3689. "  ~public:    <declaraciones>~"
  3690. "  ~private:   <declaraciones>~"
  3691. "  ~protected: <declaraciones>~"
  3692. ""
  3693. "Los especificadores de acceso (también llamados modificadores de visibili-"
  3694. "dad) pueden ser usados, dentro de una declaración de clase, en cualquier"
  3695. "orden y en cualquier frecuencia. El estilo usual es:"
  3696. ""
  3697. "  ~class clase             ~"
  3698. "  ~  {                     ~"
  3699. "  ~    private: // opcional~"
  3700. "  ~    ...                 ~"
  3701. "  ~    protected:          ~"
  3702. "  ~    ...                 ~"
  3703. "  ~    public:             ~"
  3704. "  ~    ...                 ~"
  3705. "  ~  };                    ~"
  3706. endv
  3707. beginv
  3708. coordenadas_completas 3 3 78 23
  3709. no_sombra
  3710. ""
  3711. "Si un miembro es ~public~, puede ser usado por cualquier función. En C++,"
  3712. "los miembros de un struct o union son public por defecto. Se puede cam-"
  3713. "biar el acceso de struct por defecto con private y protected; no se"
  3714. "puede cambiar el acceso de union por defecto."
  3715. ""
  3716. "Si un miembro es ~private~, sólo puede ser usado por funciones miembros y"
  3717. "amigas de la clase en la que está declarada. Los miembros de una clase"
  3718. "son private por defecto."
  3719. ""
  3720. "Si un miembro es ~protected~, su acceso es el mismo que para private. Pero"
  3721. "además el miembro puede ser usado por funciones miembros y amigas de las"
  3722. "clases derivadas de la clase declarada, pero sólo en objetos del tipo"
  3723. "derivado."
  3724. ""
  3725. "Las declaraciones de ~friend~ no son modificadas por estos especificadores"
  3726. "de acceso."
  3727. endv
  3728. beginv
  3729. coordenadas_completas 5 4 76 22
  3730. no_sombra
  3731. "Una clase base puede ser public o private con respecto a una clase"
  3732. "derivada. Si la clase base es public, los miembros public y protec-"
  3733. "ted de la clase base conservan la misma visibilidad en la clase de-"
  3734. "rivada. Si la clase base es private, los miembros public y protected"
  3735. "de la clase base son miembros private en la clase derivada. Una cla-"
  3736. "se base en C++ puede ser public o private, pero no protected. El si-"
  3737. "guiente esquema resume todo lo dicho en este párrafo:"
  3738. ""
  3739. "~Acceso en clase base  Modificador de acceso  Acceso heredado de base~"
  3740. "~--------------------  ---------------------  -----------------------~"
  3741. "~      public                  public                  public        ~"
  3742. "~      private                 public               no accesible     ~"
  3743. "~     protected                public                 protected      ~"
  3744. "~--------------------  ---------------------  -----------------------~"
  3745. "~      public                  private                 private       ~"
  3746. "~      private                 private              no accesible     ~"
  3747. "~     protected                private                 private       ~"
  3748. endv
  3749. beginvis
  3750. no_multiatributo
  3751. coordenadas_completas 3 3 78 23
  3752. borde 1
  3753. color 1 3
  3754. no_sombra
  3755. "// Ejemplo sobre los especificadores de acceso en la herencia de C++"
  3756. ""
  3757. "class base"
  3758. " {"
  3759. "   private:"
  3760. "     int base_priv;"
  3761. ""
  3762. "   protected:"
  3763. "     int base_prot;"
  3764. ""
  3765. "   public:"
  3766. "     int base_publ;"
  3767. " };"
  3768. ""
  3769. "class derpubl : public base"
  3770. " {"
  3771. "   private:"
  3772. "     int derpubl_priv;"
  3773. ""
  3774. "   protected:"
  3775. "     int derpubl_prot;"
  3776. ""
  3777. "   public:"
  3778. "     int derpubl_publ;"
  3779. " };"
  3780. ""
  3781. "class derpriv : private base"
  3782. " {"
  3783. "   private:"
  3784. "     int derpriv_priv;"
  3785. ""
  3786. "   protected:"
  3787. "     int derpriv_prot;"
  3788. ""
  3789. "   public:"
  3790. "     int derpriv_publ;"
  3791. " };"
  3792. ""
  3793. "void main (void)"
  3794. "{"
  3795. "  base cbase;"
  3796. "  derpubl cderpubl;"
  3797. "  derpriv cderpriv;"
  3798. ""
  3799. "  cbase.base_priv = 0;       // error"
  3800. "  cbase.base_prot = 0;       // error"
  3801. "  cbase.base_publ = 0;       // correcto"
  3802. ""
  3803. "  cderpubl.base_priv = 0;    // error"
  3804. "  cderpubl.base_prot = 0;    // error"
  3805. "  cderpubl.base_publ = 0;    // correcto"
  3806. "  cderpubl.derpubl_priv = 0; // error"
  3807. "  cderpubl.derpubl_prot = 0; // error"
  3808. "  cderpubl.derpubl_publ = 0; // correcto"
  3809. ""
  3810. "  cderpriv.base_priv = 0;    // error"
  3811. "  cderpriv.base_prot = 0;    // error"
  3812. "  cderpriv.base_publ = 0;    // error"
  3813. "  cderpriv.derpriv_priv = 0; // error"
  3814. "  cderpriv.derpriv_prot = 0; // error"
  3815. "  cderpriv.derpriv_publ = 0; // correcto"
  3816. "}"
  3817. endvis
  3818. beginv
  3819. coordenadas_completas 7 5 74 21
  3820. no_sombra
  3821. ""
  3822. "   ~La clase derivada tiene sus propios constructores, los~"
  3823. "   ~cuales invocarán a los constructores de la clase base.~"
  3824. ""
  3825. "   Hay una sintaxis especial para pasar argumentos desde"
  3826. "   el constructor de la clase derivada al constructor de"
  3827. "   la clase base:"
  3828. ""
  3829. "   cabecera_funcion: nombre_clase_base (lista_de_argumentos)"
  3830. ""
  3831. "   En esta sintaxis nombre_clase_base es opcional pero es"
  3832. "   aconsejable ponerlo siempre."
  3833. endv
  3834. beginvis
  3835. no_multiatributo
  3836. coordenadas_completas 3 3 78 23
  3837. borde 1
  3838. color 1 3
  3839. no_sombra
  3840. "// Ejemplo de clase derivada y clase base con constructores."
  3841. ""
  3842. "#include <iostream.h>"
  3843. ""
  3844. "class base"
  3845. " {"
  3846. "   private:"
  3847. "     int b;"
  3848. ""
  3849. "   public:"
  3850. "     base (int i = 0) { b = i; }"
  3851. "     int devb (void) { return b; }"
  3852. " };"
  3853. ""
  3854. "class derivada : public base"
  3855. "{"
  3856. "  private:"
  3857. "    int d;"
  3858. ""
  3859. "  public:"
  3860. "    derivada (int i = 0): base (i) { d = i; }"
  3861. "    derivada (int i, int j);"
  3862. "    int devd (void) { return d; }"
  3863. "};"
  3864. ""
  3865. "derivada::derivada (int i, int j): base (j) { d = i; }"
  3866. ""
  3867. "void main (void)"
  3868. "{"
  3869. "  base cb (2);"
  3870. "  derivada cd (3, 4);"
  3871. "  cout<<cb.devb()<<' '<<cd.devd()<<' '<<cd.devb(); // imprime «2 3 4»"
  3872. "}"
  3873. endvis
  3874. beginv
  3875. coordenadas_completas 9 6 72 20
  3876. no_sombra
  3877. ""
  3878. ""
  3879. "    ~Los miembros de una clase derivada pueden tener los ~"
  3880. "    ~mismos nombres de su clase base, pero serán miembros~"
  3881. "    ~diferentes aunque tengan los mismos nombres.        ~"
  3882. ""
  3883. ""
  3884. "    En este caso se puede distinguir entre los miembros"
  3885. "    de una clase y otra utilizando el operador de reso-"
  3886. "    lución de ámbito (::)."
  3887. endv
  3888. beginvis
  3889. no_multiatributo
  3890. coordenadas_completas 3 3 78 23
  3891. borde 1
  3892. color 1 3
  3893. no_sombra
  3894. "// Ejemplo de miembros con el mismo nombre en clases base y derivada."
  3895. ""
  3896. "#include <iostream.h>"
  3897. ""
  3898. "class base"
  3899. " {"
  3900. "   protected:"
  3901. "     int x;"
  3902. ""
  3903. "   public:"
  3904. "     base (int i = 0) { x = i; }"
  3905. "     int dev (void) { return x; }"
  3906. " };"
  3907. ""
  3908. "class derivada : public base"
  3909. "{"
  3910. "  protected:"
  3911. "    int x;"
  3912. ""
  3913. "  public:"
  3914. "    derivada (int i = 0): base (3 * i) { x = i; }"
  3915. "    int dev (void) { return x; }"
  3916. "    int f (void) { return x + derivada::x + base::x; }"
  3917. "    int g (void) { return dev() + derivada::dev() + base::dev(); }"
  3918. "};"
  3919. ""
  3920. "void main (void)"
  3921. "{"
  3922. "  derivada clase (2);"
  3923. "  cout << clase.dev() << ' ' << clase.derivada::dev() << ' '"
  3924. "       << clase.base::dev() << ' ' << clase.f () << ' ' << clase.g ();"
  3925. "  // imprime: «2 2 6 10 10»"
  3926. "}"
  3927. endvis
  3928. beginv
  3929. coordenadas_completas 11 7 70 19
  3930. no_sombra
  3931. ""
  3932. "~El orden de las llamadas de los constructores es: cons- ~"
  3933. "~tructor de la clase base, constructores de los miembros,~"
  3934. "~y constructor de la propia clase derivada.              ~"
  3935. ""
  3936. ""
  3937. "~Los destructores son invocados en el orden contrario:   ~"
  3938. "~destructor de la propia clase derivada, destructor de   ~"
  3939. "~los miembros, y destructor de la clase base.            ~"
  3940. endv
  3941. beginvis
  3942. no_multiatributo
  3943. coordenadas_completas 3 3 78 23
  3944. borde 1
  3945. color 1 3
  3946. no_sombra
  3947. "// Ejemplo sobre el orden de llamada de los constructores y los"
  3948. "// destructores."
  3949. ""
  3950. "#include <iostream.h>"
  3951. ""
  3952. "class a"
  3953. "  {"
  3954. "    public:"
  3955. "      a () { cout << "\nConstructor de la clase a"; }"
  3956. "      ~a () { cout << "\nDestructor de la clase a"; }"
  3957. "  };"
  3958. ""
  3959. "class b"
  3960. "  {"
  3961. "    public:"
  3962. "      b () { cout << "\nConstructor de la clase b"; }"
  3963. "      ~b () { cout << "\nDestructor de la clase b"; }"
  3964. "  };"
  3965. ""
  3966. "class c : public a"
  3967. "  {"
  3968. "    private:"
  3969. "      b claseb;"
  3970. "    public:"
  3971. "      c () { cout << "\nConstructor de la clase c"; }"
  3972. "      ~c () { cout << "\nDestructor de la clase c"; }"
  3973. "  };"
  3974. ""
  3975. "void main (void)"
  3976. "{"
  3977. "  c clasec;"
  3978. "}"
  3979. ""
  3980. "/*"
  3981. "  SALIDA DEL PROGRAMA:"
  3982. ""
  3983. "  Constructor de la clase a"
  3984. "  Constructor de la clase b"
  3985. "  Constructor de la clase c"
  3986. "  Destructor de la clase c"
  3987. "  Destructor de la clase b"
  3988. "  Destructor de la clase a"
  3989. "*/"
  3990. endvis
  3991. beginv
  3992. coordenadas_completas 13 8 68 18
  3993. no_sombra
  3994. ""
  3995. "~Hemos dicho que cuando una clase derivada tiene una~"
  3996. "~clase base privada, todos los miembros protegidos y~"
  3997. "~públicos de la clase base son privados en la clase ~"
  3998. "~derivada. A veces es deseable que algunos de estos ~"
  3999. "~miembros sean públicos o protegidos en la clase de-~"
  4000. "~rivada pero manteniendo la clase base privada.~ La"
  4001. "forma de hacerlo se ilustra en el siguiente ejemplo."
  4002. endv
  4003. beginvis
  4004. no_multiatributo
  4005. coordenadas_completas 3 3 78 23
  4006. borde 1
  4007. color 1 3
  4008. no_sombra
  4009. "// Ejemplo sobre la conversión de la visibilidad de los miembros de"
  4010. "// la clase base dentro de la clase derivada."
  4011. ""
  4012. "class b"
  4013. "  {"
  4014. "    public: int x, y, z, f(), g(), h();"
  4015. "  };"
  4016. ""
  4017. "class d : private b"
  4018. "  {"
  4019. "    private:   int b::x, b::f; // opcional: esta línea es redundante"
  4020. "    protected: int b::y, b::g; // y y g son convertidos a protected"
  4021. "    public:    int b::z, b::h; // z y y son convertidos a public"
  4022. "  };"
  4023. ""
  4024. "void main (void)"
  4025. "{"
  4026. "  b cb;"
  4027. "  d cd;"
  4028. "  cb.x = cb.y = cb.z = 0; // correcto"
  4029. "  cd.x = 0;               // error: d::x no es accesible"
  4030. "  cd.y = 0;               // error: d::y no es accesible"
  4031. "  cd.z = 0;               // correcto"
  4032. "}"
  4033. endvis
  4034. beginv
  4035. coordenadas_completas 15 9 66 17
  4036. no_sombra
  4037. ""
  4038. ""
  4039. "   De la misma forma, ~un miembro transmitido ~"
  4040. "   ~públicamente puede ser convertido explíci-~"
  4041. "   ~tamente a private o protected.            ~"
  4042. endv
  4043. beginvis
  4044. no_multiatributo
  4045. coordenadas_completas 3 3 78 23
  4046. borde 1
  4047. color 1 3
  4048. no_sombra
  4049. "// Ejemplo sobre la conversión de la visibilidad de miembros transmitidos"
  4050. "// públicamente de la clase base a la clase derivada."
  4051. ""
  4052. "class b"
  4053. "  {"
  4054. "    private:   int x, f();"
  4055. "    protected: int y, g();"
  4056. "    public:    int z, h();"
  4057. "  };"
  4058. ""
  4059. "class d : public b"
  4060. "  {"
  4061. "    public:    int b::x, b::f;// x y f convertidos de private a public"
  4062. "    private:   int b::y, b::g;// y y g convertidos de protected a private"
  4063. "    protected: int b::z, b::h;// z y h convertidos de public a protected"
  4064. "  };"
  4065. ""
  4066. "void main (void)"
  4067. "{"
  4068. "  b cb;"
  4069. "  d cd;"
  4070. ""
  4071. "  cb.x = 0; // error: b::x no es accesible"
  4072. "  cd.x = 0; // correcto"
  4073. ""
  4074. "  cb.z = 0; // correcto"
  4075. "  cd.z = 0; // error: d::z no es accesible"
  4076. "}"
  4077. endvis
  4078. partir
  4079. beginv
  4080. borde 2   este borde es necesario debido a partir
  4081. cabecera " PUNTEROS "
  4082. color 15 6
  4083. coordenadas_completas 1 2 80 24
  4084. ""
  4085. "~Una clase derivada públicamente es un subtipo de su clase base.~"
  4086. ""
  4087. "Si una clase derivada tiene una clase base pública, entonces un puntero a la"
  4088. "clase derivada puede ser asignado a una variable de tipo puntero a la clase"
  4089. "base sin hacer uso de la conversión de tipo explícita. Por ejemplo:"
  4090. ""
  4091. "  void main (void)"
  4092. "  {"
  4093. "    class base { /* ... */ };"
  4094. "    class derivada: public base { /* ... */ };"
  4095. "    derivada d;"
  4096. "    base *pb = &d;        // conversión implícita"
  4097. "    derivada *pd = pb;    // error: un base* no es un derivada*"
  4098. "    pd = (derivada *) pb; // conversión explícita"
  4099. "  }"
  4100. ""
  4101. "~En otras palabras, un objeto de una clase derivada puede ser tratado como  ~"
  4102. "~un objeto de su clase base cuando se manipula a través de punteros. Lo con-~"
  4103. "~trario no es cierto.                                                       ~"
  4104. endv
  4105. beginv
  4106. color 15 6
  4107. coordenadas_completas 3 3 78 23
  4108. no_sombra
  4109. "\         \         \         \          /         /         /         /"
  4110. "  \         \         \         \      /         /         /         /"
  4111. "    \         \         \         \  /         /         /         /"
  4112. "      \         \         \                  /         /         /"
  4113. "        \         \         \              /         /         /"
  4114. "\         \         \         \          /         /         /         /"
  4115. "  \     Cuando la clase base es privada para la clase derivada,      /"
  4116. "    \   no se hace conversión implícita de derivada* a base*.      /"
  4117. "      \ Una conversión implícita no puede ser ejecutada en este  /"
  4118. "        caso porque un miembro público de la clase base puede"
  4119. "      / ser accedido a través de un puntero a la clase base pero \"
  4120. "    /   no a través de un puntero a la clase derivada.             \"
  4121. "  /         /         /         /      \         \         \         \"
  4122. "/         /         /         /          \         \         \         \"
  4123. "        /         /         /              \         \         \"
  4124. "      /         /         /                  \         \         \"
  4125. "    /         /         /         /  \         \         \         \"
  4126. "  /         /         /         /      \         \         \         \"
  4127. "/         /         /         /          \         \         \         \"
  4128. endv
  4129. beginvis
  4130. no_multiatributo
  4131. coordenadas_completas 3 3 78 23
  4132. borde 1
  4133. color 1 3
  4134. no_sombra
  4135. "// Ejemplo de puntero a clases base y derivada."
  4136. ""
  4137. "class base"
  4138. "  {"
  4139. "    int b1;"
  4140. "    public: int b2; // b2 es un miembro público de base"
  4141. "  };"
  4142. ""
  4143. "class derivada: base"
  4144. "  {"
  4145. "    // b2 NO es un miembro público de derivada"
  4146. "  };"
  4147. ""
  4148. "void main (void)"
  4149. "{"
  4150. "  derivada d;"
  4151. ""
  4152. "// Para probar error, escribir en esta línea: #define PROBAR_ERROR"
  4153. ""
  4154. "#ifdef PROBAR_ERROR"
  4155. "  d.b2 = 2;         // error: b2 de clase base privada"
  4156. "  base *pb = &d;    // error (base privada)"
  4157. "#else"
  4158. "  base *pb;"
  4159. "#endif"
  4160. ""
  4161. "  pb->b2 = 2;       // correcto"
  4162. "  pb = (base *) &d; // correcto: conversión explícita"
  4163. "  pb->b2 = 2;       // correcto"
  4164. "}"
  4165. endvis
  4166. beginv
  4167. color 15 6
  4168. coordenadas_completas 5 4 76 22
  4169. no_sombra
  4170. "\---------------------------------|--------------------------------/"
  4171. "||\-------------------------------|------------------------------/||"
  4172. "||||\-----------------------------|----------------------------/||||"
  4173. "||||||\---------------------------|--------------------------/||||||"
  4174. "||||||||\-------------------------|------------------------/||||||||"
  4175. "||||||||||\-----------------------|----------------------/||||||||||"
  4176. "|||||~ Entre otras cosas, el ejemplo visto muestra que usando   ~|||||"
  4177. "|||||~ conversión de tipo explícita se pueden romper las reglas ~|||||"
  4178. "-----~ de protección. Está claro que no se recomienda hacer tal ~-----"
  4179. "|||||~ cosa en un programa a menos que se tenga la intención de ~|||||"
  4180. "|||||~ hacerlo ilegible.                                        ~|||||"
  4181. "||||||||||/-----------------------|----------------------\||||||||||"
  4182. "||||||||/-------------------------|------------------------\||||||||"
  4183. "||||||/---------------------------|--------------------------\||||||"
  4184. "||||/-----------------------------|----------------------------\||||"
  4185. "||/-------------------------------|------------------------------\||"
  4186. "/---------------------------------|--------------------------------\"
  4187. endv
  4188. beginv
  4189. cabecera " FUNCIONES VIRTUALES "
  4190. color 15 1
  4191. coordenadas_completas 1 2 80 24
  4192. "Hemos explicado que cuando se invoca a una función miembro sobrecargada,"
  4193. "el compilador selecciona la función de acuerdo a un algoritmo de ajuste"
  4194. "de tipos. Por ejemplo:"
  4195. "  ~class c                                  ~"
  4196. "  ~  {                                      ~"
  4197. "  ~    private: int x;                      ~"
  4198. "  ~    public:  void asig (int i) { x = i; }~"
  4199. "  ~             void asig (void) { x = 0; } ~"
  4200. "  ~  };                                     ~"
  4201. ""
  4202. "También hemos dicho que una función derivada puede tener miembros con los"
  4203. "mismos nombres que los miembros de la clase derivada. En este caso, utili-"
  4204. "zamos el operador :: para seleccionar el miembro. Por ejemplo:"
  4205. "  ~class b                                ~  ~class d: public b               ~"
  4206. "  ~  {                                    ~  ~  {                             ~"
  4207. "  ~    private: int x;                    ~  ~    private: int x;             ~"
  4208. "  ~    public:  void asig (int i=0) {x=i;}~  ~    public:  void asig (int i=0)~"
  4209. "  ~  };                                   ~  ~      { x=i; b::asig (i); } };  ~"
  4210. ""
  4211. "En los dos casos mencionados la función miembro seleccionada para ser"
  4212. "invocada es elegida en tiempo de compilación."
  4213. endv
  4214. beginv
  4215. coordenadas_completas 3 3 78 24
  4216. no_sombra
  4217. "En algunos casos interesa seleccionar dinámicamente (en tiempo de eje-"
  4218. "cución) la función miembro apropiada entre funciones de la clase base y"
  4219. "funciones de la clase derivada. La palabra clave ~virtual~ es un especi-"
  4220. "ficador de función que proporciona este mecanismo, pero sólo puede ser"
  4221. "usada para modificar declaraciones de funciones miembros."
  4222. ""
  4223. "Una función virtual debe estar definida (no sólo declarada). Se invoca"
  4224. "igual que las demás funciones. El prototipo de la función virtual en"
  4225. "la clase derivada debe ser igual que su prototipo en la clase base. Es"
  4226. "ilegal redinir una función virtual de tal manera que difiera sólo en el"
  4227. "tipo devuelto. Si dos funciones con el mismo nombre tienen diferentes"
  4228. "argumentos, C++ las considera diferentes, y el mecanimo de función vir-"
  4229. "tual es ignorado. El especificador virtual sólo es necesario ponerlo en"
  4230. "la declaración de la función de la clase base, no en la declaración de"
  4231. "la función en la clase derivada."
  4232. ""
  4233. "Las funciones virtuales deben ser miembros de alguna clase, pero no"
  4234. "pueden ser miembros estáticos (static). Una función virtual puede ser"
  4235. "amiga (friend) de otra clase. Una última restricción: los constructores"
  4236. "no pueden ser virtuales, pero los destructores sí pueden serlo."
  4237. endv
  4238. beginvis
  4239. no_multiatributo
  4240. coordenadas_completas 3 3 78 24
  4241. borde 1
  4242. color 1 3
  4243. no_sombra
  4244. "// Primer ejemplo de funciones virtuales."
  4245. ""
  4246. "#include <iostream.h>"
  4247. ""
  4248. "class b"
  4249. "  {"
  4250. "    public:"
  4251. ""
  4252. "    virtual void vf1 (void) { cout << "b::vf1 "; }"
  4253. "    virtual void vf2 (void) { cout << "b::vf2 "; }"
  4254. "    virtual void vf3 (void) { cout << "b::vf3 "; }"
  4255. "    void f (void)           { cout << "b::f ";   }"
  4256. "  };"
  4257. ""
  4258. "class d: public b"
  4259. "  {"
  4260. "    public:"
  4261. ""
  4262. "    virtual void vf1 (void) // especificador virtual es legal pero"
  4263. "    { cout << "d::vf1 "; }  // redundante"
  4264. ""
  4265. "    void vf2 (int)          // no virtual, puesto que usa una lista de"
  4266. "    { cout << "d::vf2 "; }  // argumentos diferente"
  4267. ""
  4268. "    /*"
  4269. "    char vf3 (void) { }     // ilegal: sólo cambia el tipo devuelto"
  4270. "    */"
  4271. ""
  4272. "    void f (void) { cout << "d::f "; }  // no virtual"
  4273. "  };"
  4274. ""
  4275. "void main (void)"
  4276. "{"
  4277. "  d cd;          // declara un objeto d"
  4278. "  b *pcb = &cd;  // conversión estándar de d* a b*"
  4279. ""
  4280. "  pcb->vf1();    // llama a d::vf1()"
  4281. "  pcb->vf2();    // llama a b::vf2() ya que d::vf2 tiene args. diferentes"
  4282. "  pcb->vf3();    // llama a b::vf3()"
  4283. "  pcb->f();      // llama a b::f() (no virtual)"
  4284. "  pcb->b::vf1(); // llama a b::vf1()"
  4285. "}"
  4286. ""
  4287. "/*"
  4288. "  SALIDA DE ESTE PROGRAMA:"
  4289. ""
  4290. "  d::vf1 b::vf2 b::vf3 b::f b::vf1"
  4291. "*/"
  4292. endvis
  4293. beginvis
  4294. no_multiatributo
  4295. coordenadas_completas 2 3 79 24
  4296. borde 1
  4297. color 1 3
  4298. no_sombra
  4299. "// Segundo ejemplo de funciones virtuales."
  4300. ""
  4301. "#include <iostream.h>"
  4302. ""
  4303. "class b"
  4304. "  {"
  4305. "    public:"
  4306. ""
  4307. "    int i;"
  4308. "    b (void) { i = 1; }"
  4309. "    virtual void imprimir_i (void) { cout << "\ni de clase b: " << i; }"
  4310. "  };"
  4311. ""
  4312. "class d1: public b"
  4313. "  {"
  4314. "    public:"
  4315. ""
  4316. "    d1 (void) { i = 2; }"
  4317. "    void imprimir_i (void) { cout << "\ni de clase d1: " << i; }"
  4318. "  };"
  4319. ""
  4320. "class d2: public b"
  4321. "  {"
  4322. "    public:"
  4323. ""
  4324. "    int i;"
  4325. "    d2 (void) { i = 3; }"
  4326. "    void imprimir_i (void)"
  4327. "    { cout << "\ni de clase d2: " << i << "; b::i de clase d2: " << b::i; }"
  4328. "  };"
  4329. ""
  4330. "void main (void)"
  4331. "{"
  4332. "  b cb;"
  4333. "  b *pcb = &cb;"
  4334. "  d1 cd1;"
  4335. "  d2 cd2;"
  4336. ""
  4337. "  pcb->imprimir_i (); // imprime: «i de clase b: 1»"
  4338. "  pcb = &cd1;"
  4339. "  pcb->imprimir_i (); // imprime: «i de clase d1: 2»"
  4340. "  pcb = &cd2;"
  4341. "  pcb->imprimir_i (); // imprime: «i de clase d2: 3; b::i de clase d2: 1»"
  4342. "}"
  4343. endvis
  4344. beginv
  4345. cabecera " FUNCIONES PURAS "
  4346. color 15 2
  4347. coordenadas_completas 1 2 80 24
  4348. "En la sección anterior hemos dicho que las funciones virtuales permiten"
  4349. "a las clases derivadas proporcionar diferentes versiones de una función"
  4350. "de la clase base; y también habíamos dicho que las funciones virtuales"
  4351. "deben estar definidas en la clase base al igual que todas las funciones"
  4352. "miembros. Pues bien, hay una forma de no definir una función virtual en"
  4353. "la clase base: declarándola pura."
  4354. ""
  4355. "La forma de declarar una función pura es añadiendo ~= 0~ al final de la"
  4356. "declaración virtual. Ejemplo:"
  4357. ""
  4358. "  class b"
  4359. "    {"
  4360. "      virtual void vf (int) = 0; // = 0 significa pura"
  4361. "    };"
  4362. ""
  4363. "En una clase derivada de una clase base con funciones puras, cada función"
  4364. "pura debe ser definida o redeclarada como pura."
  4365. ""
  4366. "Si una función virtual es definida en la base, no necesita ser redefinida"
  4367. "en las clases derivadas. Las llamadas simplemente llamarían a la función"
  4368. "de la clase base."
  4369. endv
  4370. beginvis
  4371. no_multiatributo
  4372. coordenadas_completas 3 3 78 23
  4373. borde 1
  4374. color 1 3
  4375. no_sombra
  4376. "// Ejemplo de funciones puras."
  4377. ""
  4378. "#include <iostream.h>"
  4379. ""
  4380. "class b"
  4381. "  {"
  4382. "    public:"
  4383. ""
  4384. "    void f1 (void)              { cout << "\nb::f1()"; }"
  4385. "    virtual void f2 (void)      { cout << "\nb::f2()"; }"
  4386. "    virtual void f3 (void)      { cout << "\nb::f3()"; }"
  4387. "    virtual void f4 (void) = 0;"
  4388. "    /*"
  4389. "    virtual void f5 (void) = 0; // ERROR: no definida en ninguna clase"
  4390. "                                // derivada"
  4391. "    */"
  4392. "  };"
  4393. ""
  4394. "class d: public b"
  4395. "  {"
  4396. "    public:"
  4397. ""
  4398. "    void f1 (void)  { cout << "\nd::f1()"; }"
  4399. "    void f2 (int)   { cout << "\nd::f2()"; }"
  4400. "    void f3 (void)  { cout << "\nd::f3()"; }"
  4401. "    void f4 (void)  { cout << "\nd::f4()"; }"
  4402. "  };"
  4403. ""
  4404. "void main (void)"
  4405. "{"
  4406. "  d cd;"
  4407. "  b *pcb = &cd;"
  4408. ""
  4409. "  pcb->f1();    // imprime: «b::f1()»"
  4410. "  pcb->f2();    // imprime: «b::f2()»"
  4411. "  pcb->f3();    // imprime: «d::f3()»"
  4412. "  pcb->f4();    // imprime: «d::f4()»"
  4413. "  /*"
  4414. "  pcb->d::f1(); // error: d no es una clase base de b"
  4415. "  */"
  4416. "  pcb->b::f3(); // imprime: «b::f3()»"
  4417. "}"
  4418. endvis
  4419. beginv
  4420. cabecera " CLASES ABSTRACTAS "
  4421. color 15 3
  4422. coordenadas_completas 1 2 80 24
  4423. ""
  4424. "~  Una clase abstracta es una clase que tiene al menos una función virtual   ~"
  4425. "~  pura.                                                                     ~"
  4426. ""
  4427. "Una clase abstracta sólo puede ser usada como una clase base para otras"
  4428. "clases."
  4429. ""
  4430. "No se puede crear ningún objeto de una clase abstracta."
  4431. ""
  4432. "Una clase abstracta no puede ser usada como el tipo de un argumento ni como"
  4433. "el tipo devuelto por una función."
  4434. ""
  4435. "Las referencias a una clase abstracta sí están permitidas, esto permite que"
  4436. "no sea necesario un objeto temporal en la inicialización."
  4437. ""
  4438. "                                    *"
  4439. "                                   ***"
  4440. "                                  ***** "
  4441. "                                   ***"
  4442. "                                    *"
  4443. ""
  4444. endv
  4445. beginvis
  4446. no_multiatributo
  4447. coordenadas_completas 3 3 78 23
  4448. borde 1
  4449. color 1 3
  4450. no_sombra
  4451. "// Ejemplo de clase abstracta."
  4452. ""
  4453. "class ca // clase abstracta"
  4454. "  {"
  4455. "    private:"
  4456. "      int x;"
  4457. "    public:"
  4458. "      void asigx (int i) { x = i; }"
  4459. "      int devx (void) { return x; }"
  4460. "      virtual void imprx (void) = 0; // función virtual pura"
  4461. "  };"
  4462. ""
  4463. "ca c;        // ERROR: intento de crear un objeto de una clase abstracta"
  4464. "ca *p;       // CORRECTO: puntero a una clase abstracta"
  4465. "ca f (void); // ERROR: el tipo devuelto no puede ser una clase abstracta"
  4466. "void g (ca); // ERROR: el tipo del argumento de una función no puede ser"
  4467. "             // una clase abstracta"
  4468. "ca& h (ca&); // CORRECTO: el tipo del valor devuelto y el tipo del"
  4469. "             // argumento de una función pueden ser una referencia"
  4470. "             // a una clase abstracta"
  4471. "ca* l (ca*); // CORRECTO:  el tipo del valor devuelto y el tipo del"
  4472. "             // argumento de una función pueden ser un puntero a una"
  4473. "             // clase abstracta"
  4474. endvis
  4475. beginv
  4476. coordenadas_completas 3 3 78 23
  4477. no_sombra
  4478. "~Supongamos que d es una clase derivada con la clase abstracta b como  ~"
  4479. "~clase base inmediata. Entonces, para cada función virtual fv en b, la ~"
  4480. "~clase d debe, o bien proporcionar una definición para fv, o bien rede-~"
  4481. "~clarar fv como pura.                                                  ~"
  4482. "// Ejemplo de definición y redeclaración de funciones puras:"
  4483. "class b"
  4484. "  {"
  4485. "    public:"
  4486. "      virtual void f (void) = 0;"
  4487. "      virtual void g (void) = 0;"
  4488. "      virtual void h (void) = 0;"
  4489. "  };"
  4490. "class d: public b // clase d derivada de clase abstracta b"
  4491. "  {"
  4492. "    public:"
  4493. "      void f (void) { } // función f definida: no realiza ninguna acción"
  4494. "      void g (void);    // función g debe estar definida en algún sitio"
  4495. "      void h (void);    // función h redeclarada como pura"
  4496. "  };"
  4497. endv
  4498. beginv
  4499. coordenadas_completas 5 4 76 22
  4500. no_sombra
  4501. "Las funciones miembros pueden ser llamadas desde un constructor"
  4502. "de una clase abstracta, pero llamar a una función virtual pura,"
  4503. "directa o indirectamente, desde tal constructor, provoca un error  /"
  4504. "en tiempo de ejecución; lo cual, por otra parte, es lógico.      /"
  4505. "/        /        /        /        /        /        /        /"
  4506. "       /        /        /        /        /        /        /"
  4507. "     /        /        /        /        /        /        /"
  4508. "   /        /        /        /        /        /        /        /"
  4509. " /        /        /        /        /        /        /        /"
  4510. "        /        /        /        /        /        /        /"
  4511. "      /        /        /        /        /        /        /"
  4512. "    /        /        /        /        /        /        /        /"
  4513. "  /        /        /        /        /        /        /        /"
  4514. "/        /        /        /        /        /        /        /"
  4515. "       /        /        /        /        /        /        /"
  4516. "     /        /        /        /        /        /        /"
  4517. "   /        /        /        /        /        /        /        /"
  4518. endv
  4519. beginvis
  4520. no_multiatributo
  4521. coordenadas_completas 7 9 74 21
  4522. borde 1
  4523. color 1 3
  4524. no_sombra
  4525. "// Ejemplo de llamada a una función pura no definida (aunque sí"
  4526. "// declarada)"
  4527. ""
  4528. "class b"
  4529. "  {"
  4530. "    public:"
  4531. ""
  4532. "    int x;"
  4533. "    b (int i = 0) { asig (i); }"
  4534. "    virtual void asig (int i) = 0;"
  4535. "  };"
  4536. ""
  4537. "class d: public b"
  4538. "  {"
  4539. "    void asig (int i) { x = i; }"
  4540. "  };"
  4541. ""
  4542. "void main (void)"
  4543. "{"
  4544. "  d cd;"
  4545. "}"
  4546. ""
  4547. "/*"
  4548. "  SALIDA DE ESTE PROGRAMA:"
  4549. ""
  4550. "  Pure virtual function called"
  4551. ""
  4552. "  NOTA:"
  4553. ""
  4554. "  El mensaje de error anterior puede variar entre distintas"
  4555. "  implementaciones de C++; este programa ha sido compilado"
  4556. "  con Borland C++ 2.0. Recalcar que el error se produce en"
  4557. "  tiempo de ejecución, no en tiempo de compilación."
  4558. "*/"
  4559. endvis
  4560. beginv
  4561. coordenadas_completas 7 5 74 21
  4562. no_sombra
  4563. ""
  4564. "  Las funciones virtuales pagan un precio por su versatilidad:"
  4565. "  cada objeto en la clase derivada necesita llevar un puntero"
  4566. "  a una tabla de funciones, necesario para seleccionar la fun-"
  4567. "  ción correcta en tiempo de ejecución."
  4568. ""
  4569. "  Por lo tanto, cuando no sea estrictamente necesario el uso"
  4570. "  de funciones virtuales, es preferible utilizar el operador"
  4571. "  de resolución de ámbito"
  4572. ""
  4573. "    nombre_de_clase::nombre_de_funcion_miembro"
  4574. ""
  4575. "  para seleccionar la función miembro a invocar."
  4576. endv
  4577. beginv
  4578. cabecera " JERARQUIA DE CLASES "
  4579. color 15 7
  4580. coordenadas_completas 1 2 80 24
  4581. "╔══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╗"
  4582. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4583. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4584. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4585. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4586. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4587. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4588. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4589. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4590. "╠══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╣"
  4591. "║~ Una clase derivada puede ser a su vez clase base de otra clase derivada. ~║"
  4592. "╠══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╦══╣"
  4593. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4594. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4595. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4596. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4597. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4598. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4599. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4600. "╠══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╬══╣"
  4601. "╚══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╩══╝"
  4602. endv
  4603. beginvis
  4604. no_multiatributo
  4605. coordenadas_completas 2 3 79 23
  4606. borde 1
  4607. color 1 3
  4608. no_sombra
  4609. "// Ejemplo de jerarquía de clases."
  4610. ""
  4611. "#include <iostream.h>"
  4612. ""
  4613. "class c1 // clase base inmediata de c1 y no inmediata de c3"
  4614. " {"
  4615. "   public:"
  4616. ""
  4617. "   int x;"
  4618. "   c1 (int i = 0) { x = i; }"
  4619. " };"
  4620. ""
  4621. "class c2: public c1 // clase derivada de c1 y base de c3"
  4622. "  {"
  4623. "    public:"
  4624. ""
  4625. "    int x;"
  4626. "    c2 (int i = 0): c1 (2 * i) { x = i; }"
  4627. "  };"
  4628. ""
  4629. "class c3: public c2 // clase derivada inmediata de c2 y no inmediata de c1"
  4630. "  {"
  4631. "    public:"
  4632. ""
  4633. "    int x;"
  4634. "    c3 (int i = 0): c2 (3 * i) { x = i; }"
  4635. "  };"
  4636. ""
  4637. "void main (void)"
  4638. "{"
  4639. "  c3 c (4);"
  4640. ""
  4641. "  cout << c.c1::x << ' '; // imprime: 24"
  4642. "  cout << c.c2::x << ' '; // imprime: 12"
  4643. "  cout << c.c3::x << ' '; // imprime: 4"
  4644. "  cout << c.x << ' ';     // imprime: 4"
  4645. "}"
  4646. endvis
  4647. end lección 6
  4648.  
  4649. ; LECCION 7
  4650. begin
  4651. beginv
  4652. borde 2
  4653. color 1 7
  4654. centrar_coordenadas
  4655. cabecera " HERENCIA MULTIPLE "
  4656. ""
  4657. "  ~                                                             ~  "
  4658. "  ~  En la lección anterior estudiamos la ~herencia simple~ (una  ~"
  4659. "  ~  clase derivada puede tener únicamente una clase base). En  ~"
  4660. "  ~  esta lección estudiaremos la ~herencia múltiple~ (una clase  ~"
  4661. "  ~  derivada puede tener más de una clase base).               ~"
  4662. "  ~                                                             ~"
  4663. ""
  4664. endv
  4665. beginv
  4666. centrar_coordenadas
  4667. cabecera " INDICE DE ESTA LECCION "
  4668. ""
  4669. "  ┌────────────────────────────────────────────────────────────────┐  "
  4670. "      ├────────────────────────────────────────────────────────┤"
  4671. ""
  4672. "      En esta lección se va a estudiar los siguientes puntos:"
  4673. ""
  4674. "      - Forma general de declarar una clase."
  4675. "      - Jerarquía circular."
  4676. "      - Ambigüedad en los miembros."
  4677. "      - Herencia virtual: clases virtuales."
  4678. "      - Orden de llamada a los constructores y los destructores."
  4679. "      - Destructores virtuales."
  4680. "      - Orden de ejecución de un programa en Turbo C++."
  4681. "      - Algunos ejemplos curiosos."
  4682. ""
  4683. "      ├────────────────────────────────────────────────────────┤"
  4684. "  └────────────────────────────────────────────────────────────────┘"
  4685. ""
  4686. endv
  4687. beginv
  4688. cabecera " FORMA GENERAL DE DECLARAR UNA CLASE "
  4689. color 14 4
  4690. coordenadas_completas 1 2 80 24
  4691. ""
  4692. "~Cuando una clase derivada tiene más de una clase base se habla de herencia~"
  4693. "~múltiple.                                                                 ~"
  4694. ""
  4695. "La forma general de declarar una clase derivada es:"
  4696. ""
  4697. "  <palabra_clave_de_clase> <nombre_de_clase>: <lista_de_clases_bases>"
  4698. "  {"
  4699. "    <lista_de_miembros>"
  4700. "  }"
  4701. ""
  4702. "donde:"
  4703. ""
  4704. "  - <palabra_clave_de_clase> es la palabra clave class, struct o union."
  4705. "  - <nombre_de_clase> debe ser un nombre único dentro de su ámbito."
  4706. "  - <lista_de_clases_bases> es la lista de clases bases separadas por comas,"
  4707. "    cada clase base en esta lista puede ir precedida por la palabra clave"
  4708. "    public o private."
  4709. "  - <lista_de_miembros> consiste en la declaración de los datos miembros y"
  4710. "    las funciones miembros."
  4711. endv
  4712. beginvis
  4713. no_multiatributo
  4714. coordenadas_completas 3 7 78 23
  4715. borde 1
  4716. color 1 3
  4717. no_sombra
  4718. "// Ejemplo de herencia múltiple."
  4719. ""
  4720. "#include <iostream.h>"
  4721. ""
  4722. "class b1"
  4723. " {"
  4724. "   public:"
  4725. ""
  4726. "   int x;"
  4727. "   b1 (int i = 0) { x = i; }"
  4728. " };"
  4729. ""
  4730. "class b2"
  4731. "  {"
  4732. "    public:"
  4733. ""
  4734. "    int x;"
  4735. "    b2 (int i = 0) { x = i; }"
  4736. "  };"
  4737. ""
  4738. "class b3"
  4739. "  {"
  4740. "    public:"
  4741. ""
  4742. "    int x;"
  4743. "    b3 (int i = 0) { x = i; }"
  4744. "  };"
  4745. ""
  4746. "class d: public b1, public b2, private b3"
  4747. "  {"
  4748. "    public:"
  4749. ""
  4750. "    int x;"
  4751. "    d (int i = 0): b1 (2 * i), b2 (3 * i), b3 (-2 * i) { x = i; }"
  4752. "  };"
  4753. ""
  4754. "void main (void)"
  4755. "{"
  4756. "  d cd (4);"
  4757. ""
  4758. "  cout << cd.b1::x << ' '; // imprime: 8"
  4759. "  cout << cd.b2::x << ' '; // imprime: 12"
  4760. "  cout << cd.d::x << ' ';  // imprime: 4"
  4761. "  cout << cd.x << ' ';     // imprime: 4"
  4762. "}"
  4763. endvis
  4764. beginv
  4765. cabecera " JERARQUIA CIRCULAR "
  4766. color 0 4
  4767. coordenadas_completas 1 2 80 24
  4768. ""
  4769. "La jerarquía circular se da cuando una clase A es base de una clase B (no"
  4770. "necesariamente base inmediata) y la clase B es base de la clase A (no nece-"
  4771. "sariamente base inmediata). Lógicamente, este tipo de jerarquía es ilegal."
  4772. "                                    ~  *     *     *     *     *     *     *~"
  4773. "Ejemplo:                            ~  *     *     *     *     *     *     *~"
  4774. "                                    ~  *     *     *     *     *     *     *~"
  4775. "  class x: z { /* ... */ };         ~  *     *     *     *     *     *     *~"
  4776. "  class y: x { /* ... */ };         ~* *     *     *     *     *     *     *~"
  4777. "  class z: y { /* ... */ };         ~        *     *     *     *     *     *~"
  4778. "                                    ~* * * * *     *     *     *     *     *~"
  4779. "Estas declaraciones son incorrectas.~              *     *     *     *     *~"
  4780. "~* * * * * * * * * * * * * * * * * * * * * * * * * *     *     *     *     *~"
  4781. "~                                                        *     *     *     *~"
  4782. "~* * * * * * * * * * * * * * * * * * * * * * * * * * * * *     *     *     *~"
  4783. "~                                                              *     *     *~"
  4784. "~* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *     *     *~"
  4785. "~                                                                    *     *~"
  4786. "~* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *     *~"
  4787. "~                                                                          *~"
  4788. "~* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *~"
  4789. endv
  4790. beginv
  4791. cabecera " AMBIGÜEDAD EN LOS MIEMBROS "
  4792. color 15 6
  4793. coordenadas_completas 1 2 80 24
  4794. "La ambigüedad en los miembros se da cuando una clase deriva miembros con"
  4795. "idéntico nombre de diferentes clases y no hay ningún miembro con ese nombre"
  4796. "en la clase derivada. Ilustremos esto con un ejemplo:"
  4797. ""
  4798. " class x { public: int f (void); };"
  4799. " class y { public: int f (void); };"
  4800. " class z: public x, public y { public: void g (void) { x::f() + y::f(); } };"
  4801. ""
  4802. " void main (void)"
  4803. " {"
  4804. "   z clase;"
  4805. "   clase.f (); // ERROR: ¿clase.x::f() o clase.y::f()?"
  4806. " }"
  4807. ""
  4808. "Hay dos formas de solucionar este problema:"
  4809. ""
  4810. "  1) Usando el operador de resolución de ámbito :: para invocar a la función"
  4811. "     f() que deseamos. De hecho, esto se ha hecho en g()."
  4812. ""
  4813. "  2) Añadir la función miembro f() a la clase derivada z. Por ejemplo:"
  4814. "     class z: ... { ... void f (void) { ... } ... };"
  4815. endv
  4816. beginvis
  4817. cabecera " HERENCIA VIRTUAL "
  4818. color 15 4
  4819. borde 2
  4820. coordenadas_completas 1 2 80 24
  4821. "Las clases virtuales se utilizan cuando una clase base se pasa más de"
  4822. "una vez a una misma clase derivada, lo cual puede ocurrir en la herencia"
  4823. "múltiple."
  4824. ""
  4825. "Una clase base no puede ser especificada más de una vez en una clase"
  4826. "derivada:"
  4827. ""
  4828. "  ~class B { ...};                   ~"
  4829. "  ~class D : B, B { ... };  // Ilegal~"
  4830. ""
  4831. "Sin embargo, una clase base se puede pasar indirectamente a una clase"
  4832. "derivada más de una vez:"
  4833. ""
  4834. "  ~class X : public B { ... }                       ~"
  4835. "  ~class Y : public B { ... }                       ~"
  4836. "  ~class Z : public X, public Y { ... }  // CORRECTO~"
  4837. ""
  4838. "En este caso, cada objeto de clase Z tendrá dos sub-objetos de clase B."
  4839. "Si esto causa probemas, se puede añadir la palabra clave virtual al"
  4840. "especificador de clase base. Por ejemplo,"
  4841. ""
  4842. "  ~class X : virtual public B { ... }  ~"
  4843. "  ~class Y : virtual public B { ... }  ~"
  4844. "  ~class Z : public X, public Y { ... }~"
  4845. ""
  4846. "B es ahora una clase base virtual, y la clase Z tiene solamente un sub-"
  4847. "objeto de clase B."
  4848. endvis
  4849. beginvis
  4850. no_posicion
  4851. no_multiatributo
  4852. cabecera " ORDEN DE LLAMADAS A LOS CONSTRUCTORES Y LOS DESTRUCTORES "
  4853. color 15 5
  4854. borde 2
  4855. coordenadas_completas 1 2 80 24
  4856. "Los constructores de la clase base son llamados en el orden que fueron"
  4857. "declarados:"
  4858. ""
  4859. "  class Y { ... };"
  4860. "  class X: public Y { ... };"
  4861. "  X clase;"
  4862. ""
  4863. "Orden de llamadas:"
  4864. ""
  4865. "  Y (); // constructor de clase base"
  4866. "  X (); // constructor de clase derivada"
  4867. ""
  4868. "Para el caso de clases bases múltiples:"
  4869. ""
  4870. "  class X: public Y, public Z { ... };"
  4871. "  X clase;"
  4872. ""
  4873. "los constructores son llamados en el orden de declaración:"
  4874. ""
  4875. "  Y (); // primero de la lista"
  4876. "  Z ();"
  4877. "  X ();"
  4878. ""
  4879. "Los constructores para las clases bases vituales son invocados antes que"
  4880. "los de cualquier otra clase base no virtual."
  4881. ""
  4882. "Si la jerarquía contiene múltiples clases bases virtuales, los construc-"
  4883. "tores de las clases bases virtuales son invocados en el orden en el cual"
  4884. "fueron declarados. Los constructores de las clases bases no virtuales son"
  4885. "invocados antes que el constructor de la clase derivada."
  4886. ""
  4887. "Si una clase virtual es derivada de una base no virtual, esa base no vir-"
  4888. "tual será llamada primero, para que la clase base virtual sea construida"
  4889. "apropiadamente."
  4890. ""
  4891. "Por ejemplo, el código"
  4892. ""
  4893. "  class X: public Y, virtual public Z { ... };"
  4894. "  X clase;"
  4895. ""
  4896. "produce el orden:"
  4897. ""
  4898. "  Z (); // inicialización de la clase base virtual"
  4899. "  Y (); // clase base no virtual"
  4900. "  X (); // clase derivada"
  4901. ""
  4902. "En el caso que una jerarquía de clases contiene múltiples instancias de"
  4903. "una clase base virtual, esa clase base es sólo construida una vez. Si,"
  4904. "sin embargo, existen las instacias virtual y no virtual de la clase base,"
  4905. "el constructor de la clase es invocado una sola vez para todas las ins-"
  4906. "tancias virtuales y una vez para cada ocurrencia no virtual de la clase"
  4907. "base."
  4908. ""
  4909. "Un ejemplo más complejo:"
  4910. ""
  4911. "  class base;"
  4912. "  class base2;"
  4913. "  class nivel1: public base2, virtual public base;"
  4914. "  class nivel2: public base2, virtual public base;"
  4915. "  class nivelalto: public nivel1, virtual public nivel2;"
  4916. "  nivelalto clase;"
  4917. ""
  4918. "El orden de los constructores es:"
  4919. ""
  4920. "  base();      // clase base virtual más alta en la jerarquía"
  4921. "               // base es construida una sóla vez"
  4922. "  base2();     // base no virtual de nivel2 virtual"
  4923. "  nivel2();    // clase base virtual"
  4924. "  base2();     // base no virtual de nivel1"
  4925. "  nivel1();    // base no virtual de nivel1"
  4926. "  nivelalto(); // clase derivada"
  4927. ""
  4928. "Antes se dijo que las clases bases son inicializadas en el orden de"
  4929. "declaración. Con los miembros ocurre lo mismo, son inicializados también"
  4930. "en orden de declaración, independientemente de la lista de inicialización."
  4931. ""
  4932. "  class X"
  4933. "  {"
  4934. "    private:"
  4935. "      int a, b;"
  4936. "    public:"
  4937. "      X (int i, int j): a (i), b (a + j) { }"
  4938. "  };"
  4939. ""
  4940. "Con esta clase, una declaración de X x (1, 1) resulta en un asignamiento"
  4941. "de 1 a x::a y de 2 a x::b."
  4942. ""
  4943. "  class base"
  4944. "  {"
  4945. "    private:"
  4946. "      int x;"
  4947. "    public:"
  4948. "      base (int i): x (i) { }"
  4949. "  };"
  4950. ""
  4951. "  class derivada: base"
  4952. "  {"
  4953. "    private:"
  4954. "      int a;"
  4955. "    public:"
  4956. "      derivada (int i): a (i * 10), base (a) { } //¡Ojo! Argumento pasado a"
  4957. "  };                                             //base no está inicializado"
  4958. ""
  4959. "Con esta clase, una llamada a d (1) no resultará en un valor de 10 para el"
  4960. "miembro x de la clase base. El valor pasado al constructor de la clase base"
  4961. "será indefinido."
  4962. ""
  4963. "Cuando se quiera una lista de inicializadores en un constructor no inline,"
  4964. "no colocar la lista en la declaración de la clase. En lugar de ello, ponerlo"
  4965. "en el punto en el cual la función es definida."
  4966. ""
  4967. "  derivada::derivada (int i): a (i)"
  4968. "  {"
  4969. "    ..."
  4970. "  }"
  4971. endvis
  4972. beginvis
  4973. no_multiatributo
  4974. coordenadas_completas 1 2 80 24
  4975. borde 1
  4976. color 1 3
  4977. no_sombra
  4978. "// Ejemplo sobre el orden de llamadas a los constructores y los destructores."
  4979. ""
  4980. "// Sería interesante para el usuario que intentara averiguar cuál es la"
  4981. "// salida antes de mirarla al final de esta ventana. Por ejemplo, observando"
  4982. "// el código fuente, podría escribir la salida del programa en un papel, y"
  4983. "// una vez hecho esto, comprobarla con la salida real que está escrita al"
  4984. "// final de esta ventana."
  4985. ""
  4986. "#include <iostream.h>"
  4987. "#include <conio.h>"
  4988. ""
  4989. "#define declarar_clase(NOMBRE_CLASE)                      \"
  4990. "  class NOMBRE_CLASE                                      \"
  4991. "    {                                                     \"
  4992. "      public:                                             \"
  4993. "        NOMBRE_CLASE ()  { cout << "\nC "#NOMBRE_CLASE; } \"
  4994. "        ~NOMBRE_CLASE () { cout << "\nD "#NOMBRE_CLASE; } \"
  4995. "    }"
  4996. ""
  4997. "declarar_clase (base1);"
  4998. "declarar_clase (base2);"
  4999. "declarar_clase (miembro1);"
  5000. "declarar_clase (miembro2);"
  5001. ""
  5002. "class derivada1: public base2, public base1"
  5003. "  {"
  5004. "    public:"
  5005. "      miembro1 m1_1, m1_2;"
  5006. "      miembro2 m2;"
  5007. "      derivada1 ()  { cout << "\nC derivada1"; }"
  5008. "      ~derivada1 () { cout << "\nD derivada1"; }"
  5009. "  };"
  5010. ""
  5011. "class derivada2: public base1, virtual public base2"
  5012. "  {"
  5013. "    public:"
  5014. "      derivada2 ()  { cout << "\nC derivada2"; }"
  5015. "      ~derivada2 () { cout << "\nD derivada2"; }"
  5016. " };"
  5017. ""
  5018. "class derivada3: virtual public derivada2, virtual public base2"
  5019. "  {"
  5020. "    public:"
  5021. "      miembro1 m1;"
  5022. "      derivada3 ()  { cout << "\nC derivada3"; }"
  5023. "      ~derivada3 () { cout << "\nD derivada3"; }"
  5024. " };"
  5025. ""
  5026. "class derivada4: virtual base2, derivada3"
  5027. "  {"
  5028. "    public:"
  5029. "      miembro1 m1_1;"
  5030. "      derivada3 d3;"
  5031. "      miembro1 m1_2;"
  5032. "      derivada4 ()  { cout << "\nC derivada4"; }"
  5033. "      ~derivada4 () { cout << "\nD derivada4"; }"
  5034. "  };"
  5035. ""
  5036. "void main (void)"
  5037. "{"
  5038. "  {"
  5039. "    cout << "\n*** Declaración de una clase derivada1";"
  5040. "    derivada1 d1;"
  5041. "  }"
  5042. "  getch ();"
  5043. ""
  5044. "  {"
  5045. "    cout << "\n*** Declaración de una clase derivada2";"
  5046. "    derivada2 d2;"
  5047. "  }"
  5048. "  getch ();"
  5049. ""
  5050. "  {"
  5051. "    cout << "\n*** Declaración de una clase derivada3";"
  5052. "    derivada3 d3;"
  5053. "  }"
  5054. "  getch ();"
  5055. ""
  5056. "  {"
  5057. "    cout << "\n*** Declaración de una clase derivada4";"
  5058. "    derivada4 d4;"
  5059. "  }"
  5060. "  getch ();"
  5061. "}"
  5062. ""
  5063. "/*"
  5064. "SALIDA DEL PROGRAMA:"
  5065. ""
  5066. "*** Declaración de una clase derivada1"
  5067. "C base2"
  5068. "C base1"
  5069. "C miembro1"
  5070. "C miembro1"
  5071. "C miembro2"
  5072. "C derivada1"
  5073. "D derivada1"
  5074. "D miembro2"
  5075. "D miembro1"
  5076. "D miembro1"
  5077. "D base1"
  5078. "D base2"
  5079. "*** Declaración de una clase derivada2"
  5080. "C base2"
  5081. "C base1"
  5082. "C derivada2"
  5083. "D derivada2"
  5084. "D base1"
  5085. "D base2"
  5086. "*** Declaración de una clase derivada3"
  5087. "C base2"
  5088. "C base1"
  5089. "C derivada2"
  5090. "C miembro1"
  5091. "C derivada3"
  5092. "D derivada3"
  5093. "D miembro1"
  5094. "D derivada2"
  5095. "D base1"
  5096. "D base2"
  5097. "*** Declaración de una clase derivada4"
  5098. "C base2"
  5099. "C base1"
  5100. "C derivada2"
  5101. "C miembro1"
  5102. "C derivada3"
  5103. "C miembro1"
  5104. "C base2"
  5105. "C base1"
  5106. "C derivada2"
  5107. "C miembro1"
  5108. "C derivada3"
  5109. "C miembro1"
  5110. "C derivada4"
  5111. "D derivada4"
  5112. "D miembro1"
  5113. "D derivada3"
  5114. "D miembro1"
  5115. "D derivada2"
  5116. "D base1"
  5117. "D base2"
  5118. "D miembro1"
  5119. "D derivada3"
  5120. "D miembro1"
  5121. "D derivada2"
  5122. "D base1"
  5123. "D base2"
  5124. "*/"
  5125. endvis
  5126. beginvis
  5127. no_multiatributo
  5128. cabecera " DESTRUCTORES VIRTUALES "
  5129. coordenadas_completas 1 2 80 24
  5130. borde 2
  5131. color 15 2
  5132. no_sombra
  5133. "Un destructor puede ser declarado como virtual. Esto permite a un puntero"
  5134. "que apunta al objeto de una clase base llamar al destructor correcto en el"
  5135. "caso de que el puntero haga referencia actualmente a un objeto de una clase"
  5136. "derivada. El destructor de una clase derivada de una clase con un destructor"
  5137. "virtual es asimismo virtual."
  5138. ""
  5139. ""
  5140. "Ejemplo:"
  5141. ""
  5142. "  class color"
  5143. "    {"
  5144. "      public:"
  5145. "        virtual ~color (); // destructor virtual para color"
  5146. "    };"
  5147. ""
  5148. "  class rojo: public color"
  5149. "    {"
  5150. "      public:"
  5151. "        ~rojo (); // destructor para rojo es virtual también"
  5152. "    };"
  5153. ""
  5154. "  class rojointenso: public rojo"
  5155. "    {"
  5156. "      public:"
  5157. "        ~rojointenso (); // destructor de rojointenso es también virtual"
  5158. "    };"
  5159. ""
  5160. "  color *paleta[3];"
  5161. ""
  5162. "  paleta[0] = new rojo;"
  5163. "  paleta[1] = new rojointenso;"
  5164. "  paleta[2] = new color;"
  5165. ""
  5166. ""
  5167. "Esto produce:"
  5168. ""
  5169. "  delete paleta[0]; // El destructor para rojo es llamado,"
  5170. "                    // seguido por el destructor para color."
  5171. ""
  5172. "  delete paleta[1]; // El destructor para rojointenso es llamado,"
  5173. "                    // seguido por ~~rojo y ~~color."
  5174. ""
  5175. "  delete paleta[2]; // El destructor para color es invocado."
  5176. ""
  5177. ""
  5178. "Sin embargo, en el caso que ningún constructor fuera declarado virtual,"
  5179. "delete paleta[0], delete paleta[1], y delete paleta[2] sólo llamarían al"
  5180. "destructor para clase color. Esto destruiría incorrectamente los dos pri-"
  5181. "meros elementos, los cuales eran actualmente de tipo rojo y rojointenso."
  5182. ""
  5183. "Los constructores no pueden ser virtuales."
  5184. endvis
  5185. begint
  5186. beginvis
  5187. no_posicion
  5188. no_multiatributo
  5189. cabecera " ORDEN DE EJECUCION DE UN PROGRAMA EN TURBO C++ "
  5190. coordenadas_completas 1 2 80 24
  5191. borde 2
  5192. color 14 1
  5193. no_sombra
  5194. "El orden de ejecución del final de un programa en Turbo C++ (o Borland C++)"
  5195. "es el que sigue:"
  5196. ""
  5197. "- Las funciones atexit son ejecutadas en el orden que fueron insertadas."
  5198. ""
  5199. "- Las funciones #pragma exit son ejecutadas en el orden de sus códigos de"
  5200. "  prioridad."
  5201. ""
  5202. "- Los destructores para las variables globales son llamados."
  5203. ""
  5204. "El orden de ejecución al comienzo de un programa en Turbo C++ (o Borland C++)"
  5205. "es justo el contrario que el orden de terminación, es decir, invirtiendo los"
  5206. "tres puntos anteriores."
  5207. ""
  5208. "Cuando se llama a exit dentro de un programa, los destructores no son"
  5209. "llamados para las variables locales en el ámbito actual. Las variables"
  5210. "globales son destruidas en su orden normal."
  5211. ""
  5212. "Si se llama a abort en cualquier lugar de un programa, ningún destructor"
  5213. "es llamado, ni incluso para las variables con un ámbito global."
  5214. ""
  5215. ""
  5216. "La función atexit(), cuyo prototipo se encuentra en el fichero stdlib.h,"
  5217. "fue discutida en el tutor de C. Sin embargo, las directivas #pragma startup"
  5218. "y #pragma exit no se explicaron, por este motivo se estudian a continuación:"
  5219. ""
  5220. ""
  5221. " ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
  5222. "  #pragma startup <nombre_de_función> [priordidad]"
  5223. "  #pragma exit <nombre_de_función> [prioridad]~"
  5224. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  5225. ""
  5226. "La directiva #pragma startup permite al progrma especificar funciones que"
  5227. "deben ser ejecutadas al principio del programa (antes que se llame a la"
  5228. "función main)."
  5229. ""
  5230. "La directiva #pragma exit permite al programa especificar funciones que"
  5231. "deben ser ejecutadas al final del programa (justo después de que el programa"
  5232. "termina con _exit)."
  5233. ""
  5234. ""
  5235. " <nombre_de_funcion>"
  5236. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  5237. "<nombre_funcion> debe ser una función previamente declarada que no toma"
  5238. "ningún argumento y devuelve void."
  5239. ""
  5240. "Debe estar declarada como"
  5241. ""
  5242. "  void func (void);"
  5243. ""
  5244. "El nombre de la función debe ser definido (o declarado) antes de la línea"
  5245. "en la que se encuentra el pragma."
  5246. ""
  5247. ""
  5248. " [prioridad]"
  5249. " ▀▀▀▀▀▀▀▀▀▀▀"
  5250. "El parámetro opcional prioridad es un entero en el rango de 64 a 255."
  5251. ""
  5252. "   0 = prioridad más alta"
  5253. " 100 = prioridad por defecto"
  5254. ""
  5255. " ┌──────────────────────────────────────────┐"
  5256. " │    No usar las prioridades de 0 to 63.   │"
  5257. " │ Ellas son usadas por las librerías de C. │"
  5258. " └──────────────────────────────────────────┘"
  5259. ""
  5260. "Las funciones con prioridades más altas son las primeras que se llaman al"
  5261. "comienzo y las últimas que se llaman al final."
  5262. endvis
  5263. beginvis
  5264. no_multiatributo
  5265. coordenadas_completas 1 2 80 24
  5266. borde 1
  5267. color 1 3
  5268. no_sombra
  5269. "// Ejemplo sobre el orden de ejecución de un programa"
  5270. ""
  5271. "#include <stdlib.h>"
  5272. "#include <iostream.h>"
  5273. ""
  5274. "#define definir_funcion(nombre_funcion) \"
  5275. "  void nombre_funcion (void) { cout << "\nFunción "#nombre_funcion"()."; }"
  5276. ""
  5277. "definir_funcion (f1);"
  5278. "definir_funcion (f2);"
  5279. "definir_funcion (f3);"
  5280. "definir_funcion (f4);"
  5281. "definir_funcion (f5);"
  5282. "definir_funcion (f6);"
  5283. ""
  5284. "#pragma startup f1 80"
  5285. "#pragma startup f2 70"
  5286. ""
  5287. "#pragma exit f5 90"
  5288. "#pragma exit f6"
  5289. ""
  5290. "#define declarar_clase(nombre_clase)                                      \"
  5291. "class nombre_clase                                                        \"
  5292. "{                                                                         \"
  5293. "  public:                                                                 \"
  5294. "    nombre_clase() { cout << "\nConstructor de clase "#nombre_clase"."; } \"
  5295. "    ~nombre_clase() { cout << "\nDestructor de clase "#nombre_clase"."; } \"
  5296. "}"
  5297. ""
  5298. "declarar_clase (x);"
  5299. "x x;"
  5300. ""
  5301. "void main (void)"
  5302. "{"
  5303. "  declarar_clase (y);"
  5304. "  y y;"
  5305. ""
  5306. "  atexit (f3);"
  5307. "  atexit (f4);"
  5308. "}"
  5309. ""
  5310. "/*"
  5311. "SALIDA DEL PROGRAMA:"
  5312. ""
  5313. "Constructor de clase x."
  5314. "Función f2()."
  5315. "Función f1()."
  5316. "Constructor de clase y."
  5317. "Destructor de clase y."
  5318. "Función f4()."
  5319. "Función f3()."
  5320. "Función f6()."
  5321. "Función f5()."
  5322. "Destructor de clase x."
  5323. "*/"
  5324. endvis
  5325. endt
  5326. beginvis
  5327. no_multiatributo
  5328. cabecera " ALGUNOS EJEMPLOS CURIOSOS "
  5329. coordenadas_completas 1 2 80 24
  5330. borde 2
  5331. color 0 7
  5332. no_sombra
  5333. "// Miscélanea de ejemplos."
  5334. ""
  5335. "#ifdef __TCPLUSPLUS__ || __BCPLUSPLUS"
  5336. "#  pragma warn -aus  // evita aviso de valor asignado y nunca usado"
  5337. "#  pragma warn -par  // evita aviso de parámetro no usado nunca"
  5338. "#endif"
  5339. ""
  5340. "class x"
  5341. "  {"
  5342. "    private:"
  5343. "      int i;"
  5344. "    public:"
  5345. "      x (void)     { /* ... */ }"
  5346. "      x (int x)    { /* ... */ }"
  5347. "      x (const x&) { /* ... */ }"
  5348. "  };"
  5349. ""
  5350. "void f1 (void)"
  5351. "{"
  5352. "  x uno;          // invoca constructor por defecto"
  5353. "  x dos (1);      // usa constructor x::x (int)"
  5354. "  x tres = 1;     // llama a x::x (int)"
  5355. "  x cuatro = uno; // invoca a x::x (const x&) para la copia"
  5356. "  x cinco (dos);  // llama a x::x (const x&)"
  5357. "}"
  5358. ""
  5359. "class base1"
  5360. "  {"
  5361. "    private:"
  5362. "      int x;"
  5363. "    public:"
  5364. "      base1 (int i) { x = i; }"
  5365. "  };"
  5366. ""
  5367. "class base2"
  5368. "  {"
  5369. "    private:"
  5370. "      int x;"
  5371. "    public:"
  5372. "      base2 (int i): x (i) { }"
  5373. "  };"
  5374. ""
  5375. "class derivada: public base1, public base2"
  5376. "  {"
  5377. "    private:"
  5378. "      int a, b;"
  5379. "    public:"
  5380. "      derivada (int i, int j): base1 (i * 2), base2 (i + j), a (i) { b = j; }"
  5381. "  };"
  5382. ""
  5383. "void f2 (void)"
  5384. "{"
  5385. "  derivada derivada (-2, 3); // inicializa base1 con -4 y base 2 con 1"
  5386. "}"
  5387. ""
  5388. "class y"
  5389. "  {"
  5390. "    public:"
  5391. "      int a, b;"
  5392. "    public:"
  5393. "      y (int i, int j): b (a + j), a (i) { } // a es inicializado antes que b"
  5394. "  };"
  5395. ""
  5396. "void f3 (void)"
  5397. "{"
  5398. "   y y (1, 2); // a es inicializado con 1 y b es inicializado con 3"
  5399. "}"
  5400. ""
  5401. "class z: virtual y"
  5402. "  {"
  5403. "    private:"
  5404. "      virtual y cy;"
  5405. "    public:"
  5406. "      z (int i, int j): cy (a, b), y (j, i) {} // y() llamado antes que cy()"
  5407. "  };"
  5408. ""
  5409. "void f4 (void)"
  5410. "{"
  5411. "  z z (1, 1); // a es inicializado con 1 y b es inicializado con 2"
  5412. "}"
  5413. ""
  5414. "void main (void)"
  5415. "{"
  5416. "  f1 ();"
  5417. "  f2 ();"
  5418. "  f3 ();"
  5419. "  f4 ();"
  5420. "}"
  5421. endvis
  5422. end lección 7
  5423.  
  5424. ; LECCION 8
  5425. begin
  5426. beginv
  5427. borde 2
  5428. color 1 7
  5429. centrar_coordenadas
  5430. cabecera " ENTRADA/SALIDA EN C++ "
  5431. " ~                                                                       ~"
  5432. ""
  5433. " ~                                                                       ~"
  5434. ""
  5435. " ~Esta lección describe la entrada y la salida en C++. La biblioteca de  ~"
  5436. " ~entrada/salida para el C, descrita por el fichero de cabecera stdio.h, ~"
  5437. " ~está todavía disponible en C++. Sin embargo, es preferible utilizar las~"
  5438. " ~bibliotecas específicas para C++. En los primeros estándares de C++, el~"
  5439. " ~conjunto de clases para los flujos de E/S estaba descrita en el fichero~"
  5440. " ~de cabecera stream.h. La utilización de este fichero se considera hoy  ~"
  5441. " ~día obsoleta. Para terminar la lección detallaremos dos ficheros de ca-~"
  5442. " ~becera (bcd.h y complex.h) que no tienen nada que ver con la E/S pero  ~"
  5443. " ~que se incluyen en esta lección por ser ésta la única en que se descri-~"
  5444. " ~ben los distintos ficheros de cabecera de C++.                         ~"
  5445. ""
  5446. " ~                                                                       ~"
  5447. ""
  5448. " ~                                                                       ~"
  5449. endv
  5450. beginv
  5451. centrar_coordenadas
  5452. cabecera " INDICE DE ESTA LECCION "
  5453. ""
  5454. "  ┌──────────────────────────────────────────────────────────────────────┐  "
  5455. "      ├──────────────────────────────────────────────────────────────┤"
  5456. ""
  5457. "      En esta lección se van a estudiar los siguientes puntos:"
  5458. ""
  5459. "      - Jerarquía de clases de E/S."
  5460. "      - Ficheros de cabecera: iostream.h, fstream.h y strstream.h."
  5461. "      - Clases definidas en iostream.h: streambuf, ios, istream,"
  5462. "        ostream, iostream, istream_withassign y ostream_withassign."
  5463. "      - Clases definidas en fstream.h: filebuf, fstreambase, ifstream,"
  5464. "        ofstream y fstream."
  5465. "      - Clases definidas en strstream.h: strstreambuf, strstreambase,"
  5466. "        istrstream, ostrstream y strstream."
  5467. "      - Clases bcd y complex."
  5468. ""
  5469. "      ├──────────────────────────────────────────────────────────────┤"
  5470. "  └──────────────────────────────────────────────────────────────────────┘"
  5471. ""
  5472. endv
  5473. borrar_pantalla
  5474. beginv
  5475. centrar_coordenadas
  5476. color 14 0
  5477. no_sombra
  5478. "ATENCION: Toda la información proporcionada en esta lección pertenece"
  5479. "al Borland C++ 2.0. La presentación de los listados (resumidos) de los"
  5480. "ficheros de cabecera es necesario tomarlos de algún compilador. En es-"
  5481. "te caso se ha tomado de dicha versión que es con la que se ha desarro-"
  5482. "llado todo el tutor. La inclusión (resumida) de los ficheros de cabe-"
  5483. "cera se ha presentado en esta lección para facilitar al usurio la com-"
  5484. "prensión de las clases declaradas en C++. Obviamente, el usuario no"
  5485. "tiene la necesidad de examinar tales listados aunque sí es muy reco-"
  5486. "mendable que lo haga para ver cómo están implementadas las clases ex-"
  5487. "plicadas. Las demás versiones de Borland C++ y de Turbo C++ así como"
  5488. "de otros compiladores que no sean Borland International deberán tener"
  5489. "descripciones similares de las clases y ficheros de cabeceras comenta-"
  5490. "dos. Si se comprende la jerarquía de clases de E/S explicada en esta"
  5491. "lección sobre el compilador citado de Borland, no se debe tener mucha"
  5492. "dificultad para comprender otra jerarquía de clases de E/S de otros"
  5493. "compiladores."
  5494. endv
  5495. borrar_pantalla
  5496. beginvis
  5497. no_multiatributo
  5498. cabecera " JERARQUIA DE CLASES DE E/S "
  5499. coordenadas_completas 1 2 80 24
  5500. color 1 3
  5501. borde 2
  5502. "                         ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
  5503. "            ╔═══╗        Clases de E/S en C++        ╔═══╗"
  5504. "            ║ios║        ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀        ║ios║"
  5505. "            ╚╤╤╤╩════════════════════════════════════╩╤╤╤╝"
  5506. "    ┌────────┘│└─────────────────┐      ▌     ┌───────┘│└──────────┐"
  5507. "╔═══╧═══╗ ╔═══╧═══╗       ╔══════╧════╗ ▌ ╔═══╧═══╗╔═══╧═══╗╔══════╧══════╗"
  5508. "║istream║ ║ostream║       ║fstreambase║ ▌ ║istream║║ostream║║strstreambase║"
  5509. "╚╤╤═╤═══╝ ╚╤═╤═╤══╝       ╚════════╤╤╤╝ ▌ ╚╤═╤════╝╚╤═╤════╝╚════╤╤╤══════╝"
  5510. " ││╔╧══════╧╗│╔╧═════════════════╗ │││  ▌  │╔╧══════╧╗└────┐┌────┘││"
  5511. " ││║iostream║│║ostream_withassign║ │││  ▌  │║iostream║╔════╧╧════╗││"
  5512. " ││╚╤══════╤╝│╚══════════════════╝ │││  ▌  │╚═══╤════╝║ostrstream║││"
  5513. " ││ │      │ └───────────────┐┌────┘││  ▌  │    │     ╚══════════╝││"
  5514. " ││ │      └────────────┐╔═══╧╧═══╗ ││  ▌  │    └──────────┐┌─────┘│"
  5515. " ││╔╧══════════════════╗│║ofstream║ ││  ▌  │          ╔════╧╧═══╗  │"
  5516. " ││║iostream_withassign║│╚════════╝ ││  ▌  │          ║strstream║  │"
  5517. " ││╚═══════════════════╝└─────┐┌────┘│  ▌  │          ╚═════════╝  │"
  5518. " │└─────────────────────┐ ╔═══╧╧══╗  │  ▌  └───────────────┐┌──────┘"
  5519. "╔╧═════════════════╗    │ ║fstream║  │  ▌             ╔════╧╧════╗"
  5520. "║istream_withassign║    │ ╚═══════╝  │  ▌             ║istrstream║"
  5521. "╚══════════════════╝    └─────┐┌─────┘  ▌             ╚══════════╝"
  5522. "▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ╔═══╧╧═══╗    ▌"
  5523. "    ╔═════════╗         ▐ ║ifstream║    ▌"
  5524. "    ║streambuf║         ▐ ╚════════╝    ▌"
  5525. "    ╚═╤═════╤═╝         ▐"
  5526. "╔═════╧═╗ ╔═╧══════════╗▐"
  5527. "║filebuf║ ║strstreambuf║▐"
  5528. "╚═══════╝ ╚════════════╝▐"
  5529. endvis
  5530. beginv
  5531. centrar_coordenadas
  5532. cabecera " FICHEROS DE CABECERA "
  5533. color 14 3
  5534. "Hay tres ficheros de cabecera en la que están declaradas las"
  5535. "clases anteriores:"
  5536. ""
  5537. "═════════════╤══════════════════════════════════════════════════"
  5538. " ~iostream.h~  │ declara los flujos básicos"
  5539. "             │"
  5540. " ~fstream.h~   │ declara las clases de flujos de C++ que soportan"
  5541. "             │ entrada y salida de ficheros"
  5542. "             │"
  5543. " ~strstream.h~ │ declara las clases de flujos de C++ para usarlas"
  5544. "             │ con arrays de bytes en memoria"
  5545. "═════════════╧══════════════════════════════════════════════════"
  5546. endv
  5547. borrar_pantalla
  5548. beginvis
  5549. cabecera " CLASES DEFINIDAS EN IOSTREAM.H "
  5550. borde 2
  5551. color 15 3
  5552. coordenadas_completas 1 2 80 24
  5553. "Clases definidas en el fichero iostream.h, desde las más primitivas hasta"
  5554. "las más especializadas:"
  5555. ""
  5556. " ════════════════════╪══════════════════════════════════════════════════════"
  5557. "  ~streambuf~          │ Proporciona métodos para los buffers de memoria."
  5558. "  ~ios~                │ Manipula errores y variables de estado de los flujos."
  5559. "  ~istream~            │ Manipula conversiones de caracteres formateadas y no"
  5560. "                     │ formateadas de un streambuf"
  5561. "  ~ostream~            │ Manipula conversiones de caracteres formateadas y no"
  5562. "                     │ formateadas de un streambuf"
  5563. "  ~iostream~           │ Combina istream y ostream para manipular operaciones"
  5564. "                     │ bidireccionales en un solo flujo."
  5565. "  ~istream_withassign~ │ Proporciona constructores y operadores de asignación"
  5566. "                     │ para el flujo cin."
  5567. "  ~ostream_withassign~ │ Proporciona constructores y operadores de asignación"
  5568. "                     │ para cout, cerr y clog."
  5569. " ════════════════════╪══════════════════════════════════════════════════════"
  5570. ""
  5571. "C++ proporciona estos objetos de flujos predefinidos:"
  5572. ""
  5573. " ══════╪════════════════════════════════════════════════════════════════════"
  5574. "  ~cin~  │ Entrada estándar, normalmente el teclado, se corresponde con stdin"
  5575. "       │ en C"
  5576. "  ~cout~ │ Salida estándar, normalmente el teclado, se corresponde con stdout"
  5577. "       │ en C"
  5578. "  ~cerr~ │ Salida de error estándar, normalmente la pantalla, se corresponde"
  5579. "       │ con stderr en C"
  5580. "  ~clog~ │ Una versión completamente buffereada de cerr (no tiene equivalente"
  5581. "       │ en C)"
  5582. " ══════╪════════════════════════════════════════════════════════════════════"
  5583. ""
  5584. "Se pueden redireccionar los flujos cin, cout, cerr y clog."
  5585. endvis
  5586. beginv
  5587. cabecera " CLASES DEFINIDAS EN FSTREAM.H "
  5588. color 15 3
  5589. centrar_coordenadas
  5590. "═════════════╪════════════════════════════════════════════════════════════"
  5591. " ~filebuf~     │ Especializa la clase streambuf para manipular ficheros."
  5592. " ~fstreambase~ │ Proporciona operaciones comunes a los flujos de ficheros."
  5593. " ~ifstream~    │ Proporciona operaciones de entrada sobre un filebuf."
  5594. " ~ofstream~    │ Proporciona operaciones de salida sobre un filebuf."
  5595. " ~fstream~     │ Proporciona operaciones simultáneas de entrada y salida"
  5596. "             │ sobre un filebuf."
  5597. "═════════════╪════════════════════════════════════════════════════════════"
  5598. endv
  5599. beginv
  5600. cabecera " CLASES DEFINIDAS EN STRSTREAM.H "
  5601. color 15 3
  5602. centrar_coordenadas
  5603. "═══════════════╪════════════════════════════════════════════════════════════"
  5604. " ~strstreambuf~  │ Especializa la clase streambuf para formatos en memoria."
  5605. " ~strstreambase~ │ Especializa la clase ios para los flujos de string."
  5606. " ~istrstream~    │ Proporciona operaciones de entrada sobre un strstreambuf."
  5607. " ~ostrstream~    │ Proporciona operaciones de salida sobre un strstreambuf."
  5608. " ~strstream~     │ Proporciona operaciones simultáneas de entrada y salida"
  5609. "               │ sobre un strstreambuf."
  5610. "═══════════════╪════════════════════════════════════════════════════════════"
  5611. ""
  5612. "Nota: en realidad, el fichero tiene el nombre de strstrea.h, ya que un"
  5613. "nombre de fichero no puede tener más de 8 caracteres en el DOS."
  5614. endv
  5615. borrar_pantalla
  5616. beginvis
  5617. no_multiatributo
  5618. cabecera " CLASE ios "
  5619. borde 2
  5620. coordenadas_completas 1 2 80 24
  5621. color 0 3
  5622. " ▄▄▄▄▄"
  5623. "  ios    Proporciona operaciones comunes a la entrada y la salida"
  5624. " ▀▀▀▀▀"
  5625. " ┌─────────┐    █▀▀▀▀▀█"
  5626. " │<ninguna>├────█ ios █───┐"
  5627. " └─────────┘    █▄▄▄▄▄█   │"
  5628. "       ┌──────────────────┘"
  5629. "       │   ┌───────────────┐"
  5630. "       ├───┤ fstreambase   │"
  5631. "       │   ╞═══════════════╡"
  5632. "       ├───┤ istream       │"
  5633. "       │   ╞═══════════════╡"
  5634. "       ├───┤ ostream       │"
  5635. "       │   ╞═══════════════╡"
  5636. "       └───┤ strstreambase │"
  5637. "           └───────────────┘"
  5638. ""
  5639. "Declarada en: iostream.h"
  5640. ""
  5641. "Las clases derivadas de ios especializan la E/S con operaciones de formato"
  5642. "de alto nivel."
  5643. ""
  5644. ""
  5645. " Constructores"
  5646. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  5647. "Asocia un streambuf dado con el flujo:"
  5648. "  ios (streambuf *);"
  5649. ""
  5650. ""
  5651. " Funciones miembros"
  5652. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  5653. " bad         clear       eof         fail        fill        flags"
  5654. " good        precision   rdbuf       rdstate     setf        tie"
  5655. " unsetf      width"
  5656. ""
  5657. ""
  5658. " Definición"
  5659. " ▀▀▀▀▀▀▀▀▀▀"
  5660. ""
  5661. "class ios"
  5662. "  {"
  5663. "    public:"
  5664. ""
  5665. "    // bits de estado de flujo"
  5666. "    enum io_state"
  5667. "      {"
  5668. "        goodbit  = 0x00,    // si está a 1, todo está correcto"
  5669. "        eofbit   = 0x01,    // 1 en fin de fichero"
  5670. "        failbit  = 0x02,    // falló la última operación de E/S"
  5671. "        badbit   = 0x04,    // se intentó una operación incorrecta"
  5672. "        hardfail = 0x80     // error irrecuperable"
  5673. "      };"
  5674. ""
  5675. "    // modo de operación del flujo"
  5676. "    enum open_mode"
  5677. "      {"
  5678. "        in   = 0x01,        // abre para lectura"
  5679. "        out  = 0x02,        // abre para escritura"
  5680. "        ate  = 0x04,        // busca fin de fichero en la apertura original"
  5681. "        app  = 0x08,        // modo añadir: todas las adiciones se hacen al"
  5682. "                            // final del fichero"
  5683. "        trunc    = 0x10,    // trunca fichero si ya existe"
  5684. "        nocreate = 0x20,    // la apertura falla si el fichero no existe"
  5685. "        noreplace= 0x40,    // la apertura falla si el fichero ya existe"
  5686. "        binary   = 0x80     // fichero binario (no de texto)"
  5687. "      };"
  5688. ""
  5689. "    // dirección de búsqueda en flujo"
  5690. "    enum seek_dir { beg=0, cur=1, end=2 };"
  5691. ""
  5692. "    // indicadores de formato"
  5693. "    enum"
  5694. "      {"
  5695. "        skipws    = 0x0001, // salta espacios en blanco en la entrada"
  5696. "        left      = 0x0002, // salida ajustada a la izquierda"
  5697. "        right     = 0x0004, // salida ajustada a la derecha"
  5698. "        internal  = 0x0008, // relleno después de signo o indicador de base"
  5699. "        dec   = 0x0010,     // conversión decimal"
  5700. "        oct   = 0x0020,     // conversión octal"
  5701. "        hex   = 0x0040,     // conversión hexadecimal"
  5702. "        showbase  = 0x0080, // usa indicador de base en la salida"
  5703. "        showpoint = 0x0100, // fuerza coma decimal (salida flotante)"
  5704. "        uppercase = 0x0200, // salida hexadecimal en mayúsculas"
  5705. "        showpos   = 0x0400, // añade '+' a los enteros positivos"
  5706. "        scientific= 0x0800, // usa notación flotante 1.2345E2"
  5707. "        fixed     = 0x1000, // usa notación flotante 123.45"
  5708. "        unitbuf   = 0x2000, // vuelca todos los flujos después de la inserc."
  5709. "        stdio     = 0x4000  // vuelca stdio y stderr después de la inserción"
  5710. "      };"
  5711. ""
  5712. "    // constantes para el segundo parámetro de seft()"
  5713. "    static const long basefield;    // dec | oct | hex"
  5714. "    static const long adjustfield;  // left | right | internal"
  5715. "    static const long floatfield;   // scientific | fixed"
  5716. ""
  5717. "    // constructor, destructor"
  5718. "    ios (streambuf *);"
  5719. "    virtual ~ios ();"
  5720. ""
  5721. "    // para leer/poner/borrar indicadores de formato"
  5722. "    long flags ();"
  5723. "    long flags (long);"
  5724. "    long setf (long _setbits, long _field);"
  5725. "    long setf (long);"
  5726. "    long unsetf (long);"
  5727. ""
  5728. "    // lee/pone anchura de campo"
  5729. "    int width ();"
  5730. "    int width (int);"
  5731. ""
  5732. "    // lee/pone carácter de relleno"
  5733. "    char fill ();"
  5734. "    char fill (char);"
  5735. ""
  5736. "    // lee/pone dígitos de precisión flotante"
  5737. "    int precision (int);"
  5738. "    int precision ();"
  5739. ""
  5740. "    // lee/pone ostream atado a este flujo"
  5741. "    ostream * tie (ostream *);"
  5742. "    ostream * tie ();"
  5743. ""
  5744. "    // obtiene estado actual del flujo"
  5745. "    int  rdstate ();         // devuelve el estado del flujo"
  5746. "    int  eof ();             // distinto de cero en fin de fichero"
  5747. "    int  fail ();            // distinto de cero si falló una operación"
  5748. "    int  bad ();             // distinto de cero si ocurrió un error"
  5749. "    int  good ();            // distinto de cero si no hay ningún bit de"
  5750. "                             // estado a 1"
  5751. "    void clear (int = 0);    // pone el estado del flujo"
  5752. "         operator void * (); // cero si estado con fallo"
  5753. "    int  operator! ();       // distinto de cero si estado con fallo"
  5754. ""
  5755. "    streambuf * rdbuf ();        // obtiene el streambuf asignado"
  5756. ""
  5757. "    // ..."
  5758. ""
  5759. "    private:"
  5760. ""
  5761. "    // ..."
  5762. ""
  5763. "    // estas declaraciones previenen la copia automática de un ios"
  5764. "    ios (ios&);             // declarado pero no definido"
  5765. "    void operator= (ios&);  // declarado pero no definido"
  5766. ""
  5767. "  };"
  5768. ""
  5769. ""
  5770. " Descripción de los métodos"
  5771. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  5772. ""
  5773. "▄▄▄▄▄"
  5774. " bad    Función miembro"
  5775. "▀▀▀▀▀"
  5776. "┌─────┬─────────────────────────────┐"
  5777. "│ ios │ No cero si ocurrió un error │"
  5778. "│     │   int bad ()                │"
  5779. "└─────┴─────────────────────────────┘"
  5780. ""
  5781. "▄▄▄▄▄▄▄"
  5782. " clear    Función miembro"
  5783. "▀▀▀▀▀▀▀"
  5784. "┌─────┬─────────────────────────────────────────┐"
  5785. "│ ios │ Pone el estado del flujo al valor dado: │"
  5786. "│     │   void clear (int = 0)                  │"
  5787. "└─────┴─────────────────────────────────────────┘"
  5788. ""
  5789. "▄▄▄▄▄"
  5790. " eof    Función miembro"
  5791. "▀▀▀▀▀"
  5792. "┌─────┬───────────────────────────┐"
  5793. "│ ios │ No cero en fin de fichero │"
  5794. "│     │   int eof ()              │"
  5795. "└─────┴───────────────────────────┘"
  5796. ""
  5797. "▄▄▄▄▄▄"
  5798. " fail    Función miembro"
  5799. "▀▀▀▀▀▀"
  5800. "┌─────┬────────────────────────────────┐"
  5801. "│ ios │ No cero si falló una operación │"
  5802. "│     │   int fail ()                  │"
  5803. "└─────┴────────────────────────────────┘"
  5804. ""
  5805. "▄▄▄▄▄▄"
  5806. " fill    Función miembro"
  5807. "▀▀▀▀▀▀"
  5808. "┌─────┬────────────────────────────────────────────────────────────┐"
  5809. "│ ios │ Devuelve el carácter actual de relleno:                    │"
  5810. "│     │   char fill ()                                             │"
  5811. "│     ├────────────────────────────────────────────────────────────┤"
  5812. "│     │ Pone carácter de relleno; devuelve el que hay previamente: │"
  5813. "│     │   char fill (char)                                         │"
  5814. "└─────┴────────────────────────────────────────────────────────────┘"
  5815. ""
  5816. "▄▄▄▄▄▄▄"
  5817. " flags    Función miembro"
  5818. "▀▀▀▀▀▀▀"
  5819. "┌─────┬─────────────────────────────────────────────────────────┐"
  5820. "│ ios │ Devuelve los indicadores del formato actual:            │"
  5821. "│     │   long flags ()                                         │"
  5822. "│     ├─────────────────────────────────────────────────────────┤"
  5823. "│     │ Pone los indicadores de formato para que sean idénticos │"
  5824. "│     │ al long dado; devuelve los indicadores previos:         │"
  5825. "│     │   long flags (long)                                     │"
  5826. "└─────┴─────────────────────────────────────────────────────────┘"
  5827. ""
  5828. "▄▄▄▄▄▄"
  5829. " good    Función miembro"
  5830. "▀▀▀▀▀▀"
  5831. "┌─────┬─────────────────────────────────────────────────────────────────────┐"
  5832. "│ ios │ No cero si no hay ningún bit de estado a 1 (no aparecieron errores) │"
  5833. "│     │   int good ()                                                       │"
  5834. "└─────┴─────────────────────────────────────────────────────────────────────┘"
  5835. ""
  5836. "▄▄▄▄▄▄▄▄▄▄▄"
  5837. " precision    Función miembro"
  5838. "▀▀▀▀▀▀▀▀▀▀▀"
  5839. "┌─────┬───────────────────────────────────────────────────────────────────┐"
  5840. "│ ios │ Pone la precisión de coma flotante; devuelve la precisión previa: │"
  5841. "│     │   int precision (int)                                             │"
  5842. "│     ├───────────────────────────────────────────────────────────────────┤"
  5843. "│     │ Devuelve la precisión actual de coma flotante:                    │"
  5844. "│     │   int precision ()                                                │"
  5845. "└─────┴───────────────────────────────────────────────────────────────────┘"
  5846. ""
  5847. "▄▄▄▄▄▄▄"
  5848. " rdbuf    Función miembro"
  5849. "▀▀▀▀▀▀▀"
  5850. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  5851. "│ ios         │ Devuelve un puntero al streambuf asignado a este flujo: │"
  5852. "│             │   streambuf* rdbuf ()                                   │"
  5853. "├─────────────┼─────────────────────────────────────────────────────────┤"
  5854. "│ fstream     │ Devuelve el buffer usado:                               │"
  5855. "│ fstreambase │   filebuf* rdbuf ()                                     │"
  5856. "│ ifstream    │                                                         │"
  5857. "│ ofstream    │                                                         │"
  5858. "└─────────────┴─────────────────────────────────────────────────────────┘"
  5859. ""
  5860. "▄▄▄▄▄▄▄▄▄"
  5861. " rdstate    Función miembro"
  5862. "▀▀▀▀▀▀▀▀▀"
  5863. "┌─────┬───────────────────────────────┐"
  5864. "│ ios │ Devuelve el estado del flujo: │"
  5865. "│     │   int rdstate ()              │"
  5866. "└─────┴───────────────────────────────┘"
  5867. ""
  5868. "▄▄▄▄▄▄"
  5869. " setf    Función miembro"
  5870. "▀▀▀▀▀▀"
  5871. "┌─────┬────────────────────────────────────────────────────────────┐"
  5872. "│ ios │ Pone a 1 los bits de _field correspondientes a los bits de │"
  5873. "│     │ _setbits:                                                  │"
  5874. "│     │   long setf (long _setbits, long _field)                   │"
  5875. "│     ├────────────────────────────────────────────────────────────┤"
  5876. "│     │ Pone a 1 los indicadores correspondientes al long dado;    │"
  5877. "│     │ devuelve los indicadores previos:                          │"
  5878. "│     │   long setf (long)                                         │"
  5879. "└─────┴────────────────────────────────────────────────────────────┘"
  5880. ""
  5881. " ▄▄▄▄▄"
  5882. "  tie    Función miembro"
  5883. " ▀▀▀▀▀"
  5884. " ┌─────┬──────────────────────────────────────────────────┐"
  5885. " │ ios │ Devuelve el flujo antado, o 0 si no hay ninguno: │"
  5886. " │     │   ostream* tie ()                                │"
  5887. " │     ├──────────────────────────────────────────────────┤"
  5888. " │     │ Ata otro flujo a éste y devuelve el flujo atado  │"
  5889. " │     │ anterior, si lo hay:                             │"
  5890. " │     │   ostream* tie (ostream*)                        │"
  5891. " └─────┴──────────────────────────────────────────────────┘"
  5892. ""
  5893. "Los flujos atados son aquéllos que son conectados de tal forma que cuando"
  5894. "uno es usado, el otro es afectado de la misma forma."
  5895. ""
  5896. "Por ejemplo, cin y cout están atados; cuando se usa cin, se vuelca cout"
  5897. "primero."
  5898. ""
  5899. "Cuando un flujo de entrada tiene caracteres para ser consumidos, o si un"
  5900. "flujo de salida necesita más caracteres, el flujo atado es volcado en"
  5901. "primer lugar automáticamente."
  5902. ""
  5903. "Por defecto, cin, cerr y clog están atados a cout."
  5904. ""
  5905. "▄▄▄▄▄▄▄▄"
  5906. " unsetf    Función miembro"
  5907. "▀▀▀▀▀▀▀▀"
  5908. "┌─────┬────────────────────────────────────────────┐"
  5909. "│ ios │ Pone a 0 los bits correspondientes al long │"
  5910. "│     │ dado; devuelve el long previo:             │"
  5911. "│     │   long unsetf (long)                       │"
  5912. "└─────┴────────────────────────────────────────────┘"
  5913. ""
  5914. "▄▄▄▄▄▄▄"
  5915. " width    Función miembro"
  5916. "▀▀▀▀▀▀▀"
  5917. "┌─────┬───────────────────────────────────────────────────┐"
  5918. "│ ios │ Devuelve la anchura atual:                        │"
  5919. "│     │   int width ()                                    │"
  5920. "│     ├───────────────────────────────────────────────────┤"
  5921. "│     │ Pone la anchura dada; devuelve la anchura previa: │"
  5922. "│     │   int width (int)                                 │"
  5923. "└─────┴───────────────────────────────────────────────────┘"
  5924. ""
  5925. ""
  5926. " Programa ejemplo"
  5927. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  5928. ""
  5929. "// Ejemplo de algunas funciones de la clase ios."
  5930. ""
  5931. "/*"
  5932. "  Los ejemplos se realizarán sobre el flujo cout que está predefinido en"
  5933. "  iostream.h. El objeto cout no es del tipo ios sino de un tipo derivado"
  5934. "  de la clase ios y por este motivo puede hacer uso de los miembros públicos"
  5935. "  y protegidos de la clase ios. Normalmente la clase ios se suele utilizar"
  5936. "  como clase base de otras clases derivadas y no directamente, por este"
  5937. "  motivo, vamos a probar las funciones de ios con el flujo cout."
  5938. "*/"
  5939. ""
  5940. "#include <iostream.h>"
  5941. "#include <conio.h>"
  5942. ""
  5943. "inline void nl (void)"
  5944. "{"
  5945. "  cout << '\n';"
  5946. "}"
  5947. ""
  5948. "void main (void)"
  5949. "{"
  5950. "  clrscr ();"
  5951. ""
  5952. "  cout << 1;                                  // imprime «1»"
  5953. "  int anchura_ant = cout.width (5);"
  5954. "  int ch_de_relleno_ant = cout.fill ('*');"
  5955. "  cout << 2;                                  // imprime «****2»"
  5956. "  cout.width (anchura_ant);"
  5957. "  cout.fill (ch_de_relleno_ant);"
  5958. "  cout << 3;                                  // imprime «3»"
  5959. ""
  5960. "  nl ();"
  5961. ""
  5962. "  // la función width() sólo afecta a la siguiente salida"
  5963. "  const numhex = 0x0F;"
  5964. "  long indicadores = cout.flags ();"
  5965. "  cout.width (4);"
  5966. "  cout.fill ('#');"
  5967. "  cout << numhex << numhex;                   // imprime «##1515»"
  5968. "  cout.width (4);"
  5969. "  cout.flags (ios::hex);"
  5970. "  cout << numhex;                             // imprime «####f»"
  5971. "  cout.width (4);"
  5972. "  cout.setf (ios::uppercase | ios::showbase);"
  5973. "  cout << numhex;                             // imprime «#0XF»"
  5974. "  cout.width (4);"
  5975. "  cout.setf (ios::left, ios::adjustfield);"
  5976. "  cout.width (4);"
  5977. "  cout << numhex;                             // imprime «0XF#»"
  5978. "  cout.unsetf (ios::uppercase);"
  5979. "  cout.width (4);"
  5980. "  cout << numhex;                             // imprime «0xf#»"
  5981. "  cout.flags (ios::dec | ios::showpos);"
  5982. "  cout.width (4);"
  5983. "  cout << numhex;                             // imprime «#+15»"
  5984. "  cout.flags (ios::left);"
  5985. "  cout.width (4);"
  5986. "  cout << numhex; // imprime «##15» con flags y «#+15» si se hubiese hecho"
  5987. "           // hecho cout.setf (ios::left) en vez de cout.flags (ios::left)"
  5988. "           // Esa es la diferencia principal entre flags() y setf()"
  5989. "  cout.flags (indicadores);"
  5990. "  cout << numhex;                             // imprime «15»"
  5991. ""
  5992. "  nl ();"
  5993. ""
  5994. "  const float numfloat = 2.3456;"
  5995. "  cout << numfloat;                           // imprime «2.3456»"
  5996. "  cout.precision (2);"
  5997. "  cout << ' ' << numfloat;                    // imprime « 2.35»"
  5998. "  cout.setf (ios::scientific);"
  5999. "  cout << ' ' << numfloat;                    // imprime « 2.35e+00»"
  6000. "  cout.setf (ios::fixed | ios::showpoint);"
  6001. "  cout << ' ' << float (int (numfloat));      // imprime «2.00»"
  6002. ""
  6003. "  nl ();"
  6004. ""
  6005. "  // la siguiente línea imprime: <valor_no_cero> <valor_no_cero> 0"
  6006. "  // donde <valor_no_cero> es un valor distinto de 0. En la sentencia"
  6007. "  // cout << cout; se realiza la conversión implícita:"
  6008. "  // cout << (void *) cout; Esto es práctico para utilizarlo en expresiones"
  6009. "  // de condiciones como las del while: while (cout) ... Aunque con el cout"
  6010. "  // puede no ser muy útil sí lo es con los objetos de tipo fstream que"
  6011. "  // veremos más adelante"
  6012. "  cout << cout << ' ' << (void *) cout << ' ' << ! cout;"
  6013. ""
  6014. "  // los modos de operación de y los bits y funciones de estado de los"
  6015. "  // flujos se probarán cuando se estudien las clases ifstream, ofstream"
  6016. "  // y fstream, que son derivadas de la clase ios y por lo tanto utilizan"
  6017. "  // todas estas características de la clase base ios"
  6018. ""
  6019. "  getch ();"
  6020. "}"
  6021. ""
  6022. endvis
  6023. beginvis
  6024. no_multiatributo
  6025. cabecera " CLASE streambuf "
  6026. borde 2
  6027. coordenadas_completas 1 2 80 24
  6028. color 0 3
  6029. " ▄▄▄▄▄▄▄▄▄▄▄"
  6030. "  streambuf    Clase para manipular buffers."
  6031. " ▀▀▀▀▀▀▀▀▀▀▀"
  6032. "                                ┌──────────────┐"
  6033. " ┌─────────┐   █▀▀▀▀▀▀▀▀▀▀▀█  ┌─┤ filebuf      │"
  6034. " │<ninguna>├───█ streambuf █──┤ ╞══════════════╡"
  6035. " └─────────┘   █▄▄▄▄▄▄▄▄▄▄▄█  └─┤ strstreambuf │"
  6036. "                                └──────────────┘"
  6037. ""
  6038. "Declarada en: iostream.h"
  6039. ""
  6040. "Normalmente, deberíamos usar las clases derivadas en nuestras aplicaciones,"
  6041. "en vez de streambuf."
  6042. ""
  6043. ""
  6044. " Constructores"
  6045. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6046. "Crea un objeto buffer vacío:"
  6047. "  streambuf ()"
  6048. ""
  6049. "Usa el array y el tamaño dados como el buffer:"
  6050. "  streambuf (char *, int)"
  6051. ""
  6052. ""
  6053. " Funciones miembros"
  6054. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6055. " in_avail      out_waiting   sbumpc        seekoff       seekpos"
  6056. " sgetc         sgetn         setbuf        snextc        sputbackc"
  6057. " sputc         sputn         stossc"
  6058. ""
  6059. ""
  6060. " Definición"
  6061. " ▀▀▀▀▀▀▀▀▀▀"
  6062. ""
  6063. "class _CLASSTYPE streambuf"
  6064. "  {"
  6065. "    public:"
  6066. ""
  6067. "    // constructores and destructores"
  6068. "    streambuf ();            // hace un streambuf vacío"
  6069. "    streambuf (char *, int); // hace un streambuf con un array de"
  6070. "                             // caracteres dado"
  6071. "    virtual ~streambuf();"
  6072. ""
  6073. "    // usa el array de caracteres proporcionado para el buffer si es posible"
  6074. "    virtual streambuf * setbuf (signed char *, int);"
  6075. "    // AVISO: esta función no es virtual; no la vuelvas a definir igual"
  6076. "    streambuf * setbuf (unsigned char *, int);"
  6077. ""
  6078. "    // obtener (extraer) caracteres"
  6079. "    int sgetc ();                       // obtiene próximo carácter"
  6080. "    int snextc ();                      // avanza y devuelve próximo carácter"
  6081. "    int sbumpc ();                      // devuelve carácter actual y avanza"
  6082. "    void stossc ();                     // avanza a próximo carácter"
  6083. "    int sgetn (char *, int);            // obtiene los próximos n caracteres"
  6084. "    virtual int do_sgetn (char *, int); // implementación de sgetn"
  6085. "    virtual int underflow ();           // llena buffer vacío"
  6086. "    int sputbackc (char);               // devuelve carácter a la entrada"
  6087. "    virtual int pbackfail (int);        // implementación de sputbackc"
  6088. "    int in_avail ();                    // número de caracteres disponibles"
  6089. "                                        // en buffer"
  6090. ""
  6091. "    // poner (insertar) caracteres"
  6092. "    int sputc (int);                  // pone un carácter"
  6093. "    int sputn (const char *, int);    // pone n caracteres de string"
  6094. "    virtual int do_sputn (const char * s, int n); // implementación de sputn"
  6095. "    virtual int overflow (int = EOF); // vuelca buffer y hace más sitio"
  6096. "    int out_waiting ();               // número de caracteres no volcados"
  6097. ""
  6098. "    // mueve puntero en flujo"
  6099. "    virtual streampos seekoff (streamoff, seek_dir,"
  6100. "                                 int = (ios::in | ios::out));"
  6101. "    virtual streampos seekpos (streampos, int = (ios::in | ios::out));"
  6102. "    virtual int sync ();"
  6103. ""
  6104. "    // ..."
  6105. "  };"
  6106. ""
  6107. ""
  6108. " Descripción de los métodos"
  6109. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6110. ""
  6111. "▄▄▄▄▄▄▄▄▄▄"
  6112. " in_avail    Función miembro"
  6113. "▀▀▀▀▀▀▀▀▀▀"
  6114. "┌───────────┬──────────────────────────────────────────────────┐"
  6115. "│ streambuf │ Devuelve el número de caracteres restantes en el │"
  6116. "│           │ buffer de entrada:                               │"
  6117. "│           │   int in_avail ()                                │"
  6118. "└───────────┴──────────────────────────────────────────────────┘"
  6119. ""
  6120. "▄▄▄▄▄▄▄▄▄▄▄▄▄"
  6121. " out_waiting    Función miembro"
  6122. "▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6123. "┌───────────┬──────────────────────────────────────────────────┐"
  6124. "│ streambuf │ Devuelve el número de caracteres restantes en el │"
  6125. "│           │ buffer de salida:                                │"
  6126. "│           │   int out_waiting ()                             │"
  6127. "└───────────┴──────────────────────────────────────────────────┘"
  6128. ""
  6129. "▄▄▄▄▄▄▄▄"
  6130. " sbumpc    Función miembro"
  6131. "▀▀▀▀▀▀▀▀"
  6132. "┌───────────┬────────────────────────────────────────────────────┐"
  6133. "│ streambuf │ Devuelve el carácter actual del buffer de entrada, │"
  6134. "│           │ entonces avanza:                                   │"
  6135. "│           │   int sbumpc ()                                    │"
  6136. "└───────────┴────────────────────────────────────────────────────┘"
  6137. ""
  6138. "▄▄▄▄▄▄▄▄▄"
  6139. " seekoff    Función miembro"
  6140. "▀▀▀▀▀▀▀▀▀"
  6141. "┌──────────────┬────────────────────────────────────────────────────────────┐"
  6142. "│ filebuf      │ Mueve el puntero de fichero relativo a la posición actual: │"
  6143. "│              │   virtual long seekoff (long, seek_dir, int)               │"
  6144. "├──────────────┼────────────────────────────────────────────────────────────┤"
  6145. "│ streambuf    │ Mueve el puntero de lectura y/o escritura (el tercer       │"
  6146. "│              │ argumento determina cuál de los dos o ambos) relativo      │"
  6147. "│              │ a la posición actual:                                      │"
  6148. "│              │   virtual long seekoff (long, seek_dir,                    │"
  6149. "│              │     int = (ios::in | ios::out))                            │"
  6150. "├──────────────┼────────────────────────────────────────────────────────────┤"
  6151. "│ strstreambuf │ Mueve el puntero relativo a la posición actual:            │"
  6152. "│              │   virtual long seekoff(long, seek_dir, int)                │"
  6153. "└──────────────┴────────────────────────────────────────────────────────────┘"
  6154. ""
  6155. "▄▄▄▄▄▄▄▄▄"
  6156. " seekpos    Función miembro"
  6157. "▀▀▀▀▀▀▀▀▀"
  6158. "┌───────────┬───────────────────────────────────────────────────────────┐"
  6159. "│ streambuf │ Mueve el puntero de lectura y/o escritura a una posición  │"
  6160. "│           │ absoluta:                                                 │"
  6161. "│           │   virtual long seekpos(long, int = (ios::in | ios::out))  │"
  6162. "└───────────┴───────────────────────────────────────────────────────────┘"
  6163. ""
  6164. "▄▄▄▄▄▄▄"
  6165. " sgetc    Función miembro"
  6166. "▀▀▀▀▀▀▀"
  6167. "┌───────────┬───────────────────────────────────────────────────────┐"
  6168. "│ streambuf │ Devuelve el próximo carácter en el buffer de entrada: │"
  6169. "│           │   int sgetc10 ()                                      │"
  6170. "└───────────┴───────────────────────────────────────────────────────┘"
  6171. ""
  6172. "▄▄▄▄▄▄▄"
  6173. " sgetn    Función miembro"
  6174. "▀▀▀▀▀▀▀"
  6175. "┌───────────┬──────────────────────────────────────────────────────────┐"
  6176. "│ streambuf │ Obtiene los próximos n caracteres del buffer de entrada: │"
  6177. "│           │   int sgetn (char*, int n)                               │"
  6178. "└───────────┴──────────────────────────────────────────────────────────┘"
  6179. ""
  6180. "▄▄▄▄▄▄▄▄"
  6181. " setbuf    Función miembro"
  6182. "▀▀▀▀▀▀▀▀"
  6183. "┌──────────────┬─────────────────────────────────────────────────┐"
  6184. "│ filebuf      │ Especifica el buffer a usar:                    │"
  6185. "│ strstreambuf │   virtual streambuf* setbuf (char*, int)        │"
  6186. "├──────────────┼─────────────────────────────────────────────────┤"
  6187. "│ fstreambase  │ Usa un buffer especificado:                     │"
  6188. "│              │   void setbuf (char*, int)                      │"
  6189. "├──────────────┼─────────────────────────────────────────────────┤"
  6190. "│ streambuf    │ Conecta a un buffer dado:                       │"
  6191. "│              │   virtual streambuf* setbuf (signed char*, int) │"
  6192. "└──────────────┴─────────────────────────────────────────────────┘"
  6193. ""
  6194. "▄▄▄▄▄▄▄▄"
  6195. " snextc    Función miembro"
  6196. "▀▀▀▀▀▀▀▀"
  6197. "┌───────────┬─────────────────────────────────────────────────┐"
  6198. "│ streambuf │ Avanza a (y devuelve el próximo carácter de) el │"
  6199. "│           │ buffer de entrada:                              │"
  6200. "│           │   int snextc ()                                 │"
  6201. "└───────────┴─────────────────────────────────────────────────┘"
  6202. ""
  6203. "▄▄▄▄▄▄▄▄▄▄▄"
  6204. " sputbackc    Función miembro"
  6205. "▀▀▀▀▀▀▀▀▀▀▀"
  6206. "┌───────────┬────────────────────────────────────┐"
  6207. "│ streambuf │ Devuelve un carácter a la entrada: │"
  6208. "│           │   int sputbackc (char)             │"
  6209. "└───────────┴────────────────────────────────────┘"
  6210. ""
  6211. "▄▄▄▄▄▄▄"
  6212. " sputc    Función miembro"
  6213. "▀▀▀▀▀▀▀"
  6214. "┌───────────┬───────────────────────────────────────────┐"
  6215. "│ streambuf │ Put one character into the output buffer: │"
  6216. "│           │   int sputc(int)                          │"
  6217. "└───────────┴───────────────────────────────────────────┘"
  6218. ""
  6219. "▄▄▄▄▄▄▄"
  6220. " sputn    Función miembro"
  6221. "▀▀▀▀▀▀▀"
  6222. "┌───────────┬───────────────────────────────────────────┐"
  6223. "│ streambuf │ Pone n caracteres en el buffer de salida: │"
  6224. "│           │   int sputn (const char*, int n)          │"
  6225. "└───────────┴───────────────────────────────────────────┘"
  6226. ""
  6227. "▄▄▄▄▄▄▄▄"
  6228. " stossc    Función miembro"
  6229. "▀▀▀▀▀▀▀▀"
  6230. "┌───────────┬─────────────────────────────────────────────────────┐"
  6231. "│ streambuf │ Avanza al próximo carácter en el buffer de entrada: │"
  6232. "│           │   void stossc ()                                    │"
  6233. "└───────────┴─────────────────────────────────────────────────────┘"
  6234. ""
  6235. ""
  6236. " Programa ejemplo"
  6237. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6238. ""
  6239. "// Este ejemplo prueba algunos métodos (funciones miembros) de la clase"
  6240. "// streambuf."
  6241. ""
  6242. "/*"
  6243. "  Los ejemplos se realizarán accediendo al streambuf de los flujos cout y"
  6244. "  cin a través de la función miembro rdbuf() de la clase ios. Los objetos"
  6245. "  cout y cin no son del tipo ios sino de un tipo derivado de la clase ios"
  6246. "  y por este motivo pueden hacer uso de los miembros públicos y protegidos"
  6247. "  de la clase ios."
  6248. "*/"
  6249. ""
  6250. "#include <iostream.h>"
  6251. ""
  6252. "#define nl << "\n""
  6253. ""
  6254. "void main (void)"
  6255. "{"
  6256. "  cout << char ((cin.rdbuf())->sputbackc ('X'))  nl; // imprime «X»"
  6257. "  cout << (cin.rdbuf())->in_avail ()             nl; // imprime «1»"
  6258. "  cout << char ((cin.rdbuf())->sgetc())          nl; // imprime «X»"
  6259. "  cout << char ((cout.rdbuf())->sputbackc ('X')) nl; // imprime «X»"
  6260. "  cout << (cout.rdbuf())->out_waiting ()         nl; // imprime «0»"
  6261. "  cout << char ((cout.rdbuf())->sputc('X'))      nl; // imprime «XX»"
  6262. "}"
  6263. ""
  6264. endvis
  6265. beginvis
  6266. no_multiatributo
  6267. cabecera " CLASE istream "
  6268. borde 2
  6269. coordenadas_completas 1 2 80 24
  6270. color 0 3
  6271. " ▄▄▄▄▄▄▄▄▄"
  6272. "  istream    Proporciona entrada formateada y no formateada de un streambuf"
  6273. " ▀▀▀▀▀▀▀▀▀"
  6274. " ┌─────┐   █▀▀▀▀▀▀▀▀▀█"
  6275. " │ ios ├───█ istream █───┐"
  6276. " └─────┘   █▄▄▄▄▄▄▄▄▄█   │"
  6277. "   ┌─────────────────────┘"
  6278. "   │   ┌────────────────────┐"
  6279. "   ├───┤ ifstream           │"
  6280. "   │   ╞════════════════════╡"
  6281. "   ├───┤ iostream           │"
  6282. "   │   ╞════════════════════╡"
  6283. "   ├───┤ istream_withassign │"
  6284. "   │   ╞════════════════════╡"
  6285. "   └───┤ istrstream         │"
  6286. "       └────────────────────┘"
  6287. ""
  6288. "Declarada en: iostream.h"
  6289. ""
  6290. ""
  6291. " Constructores"
  6292. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6293. "Asocia un streambuf dado con el flujo:"
  6294. "  istream (streambuf *)"
  6295. ""
  6296. ""
  6297. " Funciones miembros"
  6298. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6299. " gcount    get       getline   ignore    peek      putback   read"
  6300. " seekg     tellg"
  6301. ""
  6302. ""
  6303. " Definición"
  6304. " ▀▀▀▀▀▀▀▀▀▀"
  6305. ""
  6306. "class istream : virtual public ios"
  6307. "  {"
  6308. "    public:"
  6309. ""
  6310. "    // constructor y destructor"
  6311. "    istream (streambuf *);"
  6312. "    virtual ~istream ();"
  6313. ""
  6314. "    // ..."
  6315. ""
  6316. "    // pone/lee la posición del puntero de lectura"
  6317. "    istream& seekg (streampos);"
  6318. "    istream& seekg (streamoff, seek_dir);"
  6319. "    streampos tellg ();"
  6320. ""
  6321. "    int sync ();"
  6322. ""
  6323. "    /*"
  6324. "     * Operaciones de extracción no formateadas"
  6325. "     */"
  6326. "    // extrae caracteres colocándolos en un array"
  6327. "    istream& get (signed char *, int, char = '\n');"
  6328. "    istream& get (unsigned char *, int, char = '\n');"
  6329. "    istream& read (signed char *, int);"
  6330. "    istream& read (unsigned char *, int);"
  6331. ""
  6332. "    // extrae caracteres colocándolos en un array hasta encontrar el"
  6333. "    // carácter de terminación dado como máximo"
  6334. "    istream& getline (signed char *, int, char = '\n');"
  6335. "    istream& getline (unsigned char *, int, char = '\n');"
  6336. ""
  6337. "    // extrae caracteres colocándolos en un streambuf hasta encontrar el"
  6338. "    // carácter de terminación dado como máximo"
  6339. "    istream& get (streambuf&, char = '\n');"
  6340. ""
  6341. "    // extrae un solo carácter"
  6342. "    istream& get (unsigned char&);"
  6343. "    istream& get (signed char&);"
  6344. "    int      get ();"
  6345. ""
  6346. "    int      peek ();        // devuelve próximo carácter sin extracción"
  6347. "    int      gcount ();      // número de caracteres no formateados en la"
  6348. "                             // última extracción"
  6349. "    istream& putback (char); // devuelve un carácter a la entrada"
  6350. ""
  6351. "    // extrae y desecha caracteres pero para al encontrar el delimitador"
  6352. "    istream& ignore (int = 1, int = EOF);"
  6353. ""
  6354. "    /*"
  6355. "     * Operaciones de extracción formateadas"
  6356. "     */"
  6357. "    istream& operator>> (istream& (*_f) (istream&));"
  6358. "    istream& operator>> (ios& (*_f) (ios&));"
  6359. "    istream& operator>> (signed char *);"
  6360. "    istream& operator>> (unsigned char *);"
  6361. "    istream& operator>> (unsigned char&);"
  6362. "    istream& operator>> (signed char&);"
  6363. "    istream& operator>> (short&);"
  6364. "    istream& operator>> (int&);"
  6365. "    istream& operator>> (long&);"
  6366. "    istream& operator>> (unsigned short&);"
  6367. "    istream& operator>> (unsigned int&);"
  6368. "    istream& operator>> (unsigned long&);"
  6369. "    istream& operator>> (float&);"
  6370. "    istream& operator>> (double&);"
  6371. "    istream& operator>> (long double&);"
  6372. ""
  6373. "    // extrae de este istream, insertando en streambuf"
  6374. "    istream& operator>> (streambuf *);"
  6375. ""
  6376. "    protected:"
  6377. ""
  6378. "    istream ();"
  6379. "    void eatwhite ();  // extrae espacios blancos consecutivos"
  6380. ""
  6381. "    private:"
  6382. ""
  6383. "    // ..."
  6384. "  };"
  6385. ""
  6386. ""
  6387. " Descripción de los métodos"
  6388. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6389. ""
  6390. "▄▄▄▄▄▄▄▄"
  6391. " gcount    Función miembro"
  6392. "▀▀▀▀▀▀▀▀"
  6393. "┌─────────┬──────────────────────────────────────────────────┐"
  6394. "│ istream │ Devuelve el número de caracteres extraídos en la │"
  6395. "│         │ última operación:                                │"
  6396. "│         │   int gcount ()                                  │"
  6397. "└─────────┴──────────────────────────────────────────────────┘"
  6398. ""
  6399. "▄▄▄▄▄"
  6400. " get    Función miembro"
  6401. "▀▀▀▀▀"
  6402. "┌─────────┬───────────────────────────────────────────────────────────────┐"
  6403. "│ istream │ Extrae el próximo carácter o EOF:                             │"
  6404. "│         │   int get ()                                                  │"
  6405. "│         ├───────────────────────────────────────────────────────────────┤"
  6406. "│         │ Extra caracteres colocándolos en el char * dado hasta que el  │"
  6407. "│         │ delimitador (tercer parámetro) o el fin-de-fichero es encon-  │"
  6408. "│         │ trado, o hasta que (len - 1) bytes han sido leídos:           │"
  6409. "│         │   istream& get (signed char*, int len, char = '\n')           │"
  6410. "│         │   istream& get (unsigned char*, int len, char = '\n')         │"
  6411. "│         │                                                               │"
  6412. "│         │   ■ Un nulo de terminación es siempre colocado en el string   │"
  6413. "│         │     de salida; el delimitador nunca es colocado.              │"
  6414. "│         │   ■ Falla sólamente si no es extraído ningún carácter.        │"
  6415. "│         ├───────────────────────────────────────────────────────────────┤"
  6416. "│         │ Extra un solo carácter colocándolo en la referencia a         │"
  6417. "│         │ carácter dada:                                                │"
  6418. "│         │   istream& get (unsigned char&)                               │"
  6419. "│         │   istream& get (signed char&)                                 │"
  6420. "│         ├───────────────────────────────────────────────────────────────┤"
  6421. "│         │ Extrae caracteres colocándolos en el streambuf dado hasta que │"
  6422. "│         │ se encuentra el delimitador:                                  │"
  6423. "│         │   istream& get (streambuf&, char = '\n')                      │"
  6424. "└─────────┴───────────────────────────────────────────────────────────────┘"
  6425. ""
  6426. "▄▄▄▄▄▄▄▄▄"
  6427. " getline    Función miembro"
  6428. "▀▀▀▀▀▀▀▀▀"
  6429. "┌─────────┬──────────────────────────────────────────────────────────────┐"
  6430. "│ istream │ Igual que get, excepto que también se extrae el delimitador: │"
  6431. "│         │   istream& getline (signed char*, int, char = '\n')          │"
  6432. "│         │   istream& getline (unsigned char*, int, char = '\n')        │"
  6433. "└─────────┴──────────────────────────────────────────────────────────────┘"
  6434. ""
  6435. "▄▄▄▄▄▄▄▄"
  6436. " ignore    Función miembro"
  6437. "▀▀▀▀▀▀▀▀"
  6438. "┌─────────┬─────────────────────────────────────────────────────────┐"
  6439. "│ istream │ Salta un máximo de n caracteres en el flujo de entrada; │"
  6440. "│         │ para cuando encuentra el delimitador:                   │"
  6441. "│         │   istream& ignore (int n = 1, int delim = EOF)          │"
  6442. "└─────────┴─────────────────────────────────────────────────────────┘"
  6443. ""
  6444. "▄▄▄▄▄▄"
  6445. " peek    Función miembro"
  6446. "▀▀▀▀▀▀"
  6447. "┌─────────┬───────────────────────────────────────────┐"
  6448. "│ istream │ Devuelve próximo carácter sin extracción: │"
  6449. "│         │   int peek ()                             │"
  6450. "└─────────┴───────────────────────────────────────────┘"
  6451. ""
  6452. "▄▄▄▄▄▄▄▄▄"
  6453. " putback    Función miembro"
  6454. "▀▀▀▀▀▀▀▀▀"
  6455. "┌─────────┬────────────────────────────────┐"
  6456. "│ istream │ Devuelve un carácter al flujo: │"
  6457. "│         │   istream& putback (char)      │"
  6458. "└─────────┴────────────────────────────────┘"
  6459. ""
  6460. "▄▄▄▄▄▄"
  6461. " read    Función miembro"
  6462. "▀▀▀▀▀▀"
  6463. "┌─────────┬───────────────────────────────────────────────────────────────┐"
  6464. "│ istream │ Extrae un número dado de caracteres colocándolos en un array: │"
  6465. "│         │   istream& read (signed char*, int)                           │"
  6466. "│         │   istream& read (unsigned char*, int)                         │"
  6467. "│         │                                                               │"
  6468. "│         │ Usa gcount() para determinar el número de caracteres leídos   │"
  6469. "│         │ realmente si ocurre un error.                                 │"
  6470. "└─────────┴───────────────────────────────────────────────────────────────┘"
  6471. ""
  6472. "▄▄▄▄▄▄▄"
  6473. " seekg    Función miembro"
  6474. "▀▀▀▀▀▀▀"
  6475. "┌─────────┬─────────────────────────────────────────────────────────┐"
  6476. "│ istream │ Mueve a una posición absoluta (normalmente el argumento │"
  6477. "│         │ es el valor devuelto por tellg):                        │"
  6478. "│         │   istream& seekg (long)                                 │"
  6479. "│         ├─────────────────────────────────────────────────────────┤"
  6480. "│         │ Mueve a una posición relativa a la posición actual:     │"
  6481. "│         │   istream& seekg (long, seek_dir)                       │"
  6482. "│         │                                                         │"
  6483. "│         │ Usa esta definición para seek_dir:                      │"
  6484. "│         │   enum seek_dir { beg, cur, end };                      │"
  6485. "└─────────┴─────────────────────────────────────────────────────────┘"
  6486. ""
  6487. "▄▄▄▄▄▄▄"
  6488. " tellg    Función miembro"
  6489. "▀▀▀▀▀▀▀"
  6490. "┌─────────┬────────────────────────────────────────┐"
  6491. "│ istream │ Devuelve la posición actual del flujo: │"
  6492. "│         │   long tellg ()                        │"
  6493. "└─────────┴────────────────────────────────────────┘"
  6494. ""
  6495. ""
  6496. " Programa ejemplo"
  6497. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6498. ""
  6499. "// Este ejemplo prueba todos los métodos (funciones miembros) de la clase"
  6500. "// istream."
  6501. ""
  6502. "/*"
  6503. "  Los ejemplos se realizarán sobre el flujo cin que está predefinido en"
  6504. "  iostream.h. El objeto cin no es del tipo istream sino de un tipo derivado"
  6505. "  de la clase istream y por este motivo puede hacer uso de los miembros"
  6506. "  públicos y protegidos de la clase istream."
  6507. "*/"
  6508. ""
  6509. "#include <iostream.h>"
  6510. "#include <conio.h>"
  6511. ""
  6512. "void main (void)"
  6513. "{"
  6514. "  const tam = 100;"
  6515. "  char cad1[tam], cad2[tam];"
  6516. ""
  6517. "  cout << "Introduce dos líneas:\n";"
  6518. "  cin.getline (cad1, tam).getline (cad2, tam);"
  6519. "  cout << "Primera línea: " << cad1 << "\nSegunda línea: " << cad2;"
  6520. ""
  6521. "  cout << "\n\nIntroduce una serie de caracteres terminados con * que ""
  6522. "          "serán ignorados: ";"
  6523. "  cin.ignore (tam, '*');"
  6524. ""
  6525. "  cout << "\nIntroduce 5 caracteres: ";"
  6526. "  cin.read (cad1, 5);"
  6527. "  cout << "Cadena leída: " << (cad1[cin.gcount()] = 0, cad1);"
  6528. ""
  6529. "  cout << "\nIntroduce un carácter:\n";"
  6530. "  cout << "Carácter leído sin extracción: " << char (cin.peek ());"
  6531. "  cout << "\nCarácter leído con extracción, devuelto y leído de nuevo: ""
  6532. "       << char (cin.putback(cin.get()).get());"
  6533. ""
  6534. "  cout << "\n\nPosición actual en flujo cin leída, puesta y leída de nuevo: ""
  6535. "       << cin.seekg (cin.tellg ()).tellg ();"
  6536. ""
  6537. "  cout << "\n\nPulsa una tecla para finalizar.";"
  6538. "  getch ();"
  6539. "}"
  6540. ""
  6541. "/*"
  6542. "SALIDA:"
  6543. ""
  6544. "«"
  6545. "Introduce dos líneas:"
  6546. "abc"
  6547. "d e f"
  6548. "Primera línea: abc"
  6549. "Segunda línea: d e f"
  6550. ""
  6551. "Introduce una serie de caracteres terminados con * que serán ignorados: as"
  6552. "df"
  6553. "g"
  6554. "h j*"
  6555. ""
  6556. "Introduce 5 caracteres: qwert"
  6557. "Cadena leída:"
  6558. "qwer"
  6559. "Introduce un carácter:"
  6560. "Carácter leído sin extracción: t"
  6561. "Carácter leído con extracción, devuelto y leído de nuevo: t"
  6562. ""
  6563. "Posición actual en flujo cin leída, puesta y leída de nuevo: 11974"
  6564. ""
  6565. "Pulsa una tecla para finalizar."
  6566. "»"
  6567. ""
  6568. "OBSERVACIONES SOBRE LA SALIDA DEL PROGRAMA:"
  6569. ""
  6570. "1) Observando el programa nos damos cuenta de que parte de la salida"
  6571. "mostrada corresponde a caracteres introducidos por teclado y visualizados"
  6572. "en la pantalla."
  6573. ""
  6574. "2) En la función read, al leer 5 caracteres, lee primero el carácter nueva"
  6575. "línea que se encuentra en el buffer pues se pulsó la tecla ENTER después"
  6576. "del *."
  6577. ""
  6578. "3) La función read no lee el carácter t pues le hemos dicho que lea"
  6579. "solamente 5 caracteres. Por lo tanto, el carácter t queda en el buffer"
  6580. "de entrada y la función get, que sigue a la read, lee el carácter que"
  6581. "se encuentra en el buffer en vez de pedir un carácter por teclado."
  6582. ""
  6583. "4) El número 11974 es distinto en cada ejecución del programa. Las funciones"
  6584. "seekg() y tellg() son realmente útiles al leer ficheros de discos."
  6585. "*/"
  6586. ""
  6587. endvis
  6588. beginvis
  6589. no_multiatributo
  6590. cabecera " CLASE ostream "
  6591. borde 2
  6592. coordenadas_completas 1 2 80 24
  6593. color 0 3
  6594. " ▄▄▄▄▄▄▄▄▄"
  6595. "  ostream    Proporciona salida formateada y no formateada a un streambuf."
  6596. " ▀▀▀▀▀▀▀▀▀"
  6597. ""
  6598. " ┌─────┐   █▀▀▀▀▀▀▀▀▀█"
  6599. " │ ios ├───█ ostream █───┐"
  6600. " └─────┘   █▄▄▄▄▄▄▄▄▄█   │"
  6601. "   ┌─────────────────────┘"
  6602. "   │   ┌────────────────────┐"
  6603. "   ├───┤ iostream           │"
  6604. "   │   ╞════════════════════╡"
  6605. "   ├───┤ ofstream           │"
  6606. "   │   ╞════════════════════╡"
  6607. "   ├───┤ ostream_withassign │"
  6608. "   │   ╞════════════════════╡"
  6609. "   └───┤ ostrstream         │"
  6610. "       └────────────────────┘"
  6611. ""
  6612. "Declarada en: iostream.h"
  6613. ""
  6614. ""
  6615. " Constructores"
  6616. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6617. "Asocia un streambuf dado con el flujo:"
  6618. "  ostream (streambuf *)"
  6619. ""
  6620. ""
  6621. " Funciones miembros"
  6622. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6623. " flush   seekp   put     tellp   write"
  6624. ""
  6625. ""
  6626. " Definición"
  6627. " ▀▀▀▀▀▀▀▀▀▀"
  6628. ""
  6629. "class ostream : virtual public ios"
  6630. "  {"
  6631. "    public:"
  6632. ""
  6633. "    // constructores y destructores"
  6634. "    ostream (streambuf *);"
  6635. "    virtual ~ostream ();"
  6636. ""
  6637. "    // ..."
  6638. ""
  6639. "    ostream& flush ();"
  6640. ""
  6641. "    // pone/lee la posición del puntero de escritura"
  6642. "    ostream&  seekp (streampos);"
  6643. "    ostream&  seekp (streamoff, seek_dir);"
  6644. "    streampos tellp ();"
  6645. ""
  6646. "    /*"
  6647. "     * Operaciones de inserción no formateadas"
  6648. "     */"
  6649. "    ostream& put (char);                          // inserta el carácter"
  6650. "    ostream& write (const signed char  *, int);   // inserta el string"
  6651. "    ostream& write (const unsigned char  *, int); // inserta el string"
  6652. ""
  6653. "    /*"
  6654. "     * Operaciones de inserción formateadas"
  6655. "     */"
  6656. "    // inserta el carácter"
  6657. "    ostream& operator<< (signed char);"
  6658. "    ostream& operator<< (unsigned char);"
  6659. ""
  6660. "    // para lo siguiente, inserta representación del valor númerico"
  6661. "    ostream& operator<< (short);"
  6662. "    ostream& operator<< (unsigned short);"
  6663. "    ostream& operator<< (int);"
  6664. "    ostream& operator<< (unsigned int);"
  6665. "    ostream& operator<< (long);"
  6666. "    ostream& operator<< (unsigned long);"
  6667. "    ostream& operator<< (float);"
  6668. "    ostream& operator<< (double);"
  6669. "    ostream& operator<< (long double);"
  6670. ""
  6671. "    // inserta string terminado en nulo"
  6672. "    ostream& operator<< (const signed char *);"
  6673. "    ostream& operator<< (const unsigned char *);"
  6674. ""
  6675. "    // inserta representación del valor del puntero"
  6676. "    ostream& operator<< (void *);"
  6677. ""
  6678. "    // extrae de streambuf, insertando en este otream"
  6679. "    ostream& operator<< (streambuf *);"
  6680. ""
  6681. "    // manipuladores"
  6682. "    ostream& operator<< (ostream& (*_f) (ostream&));"
  6683. "    ostream& operator<< (ios& (*_f) (ios&));"
  6684. ""
  6685. "    protected:"
  6686. ""
  6687. "    // ..."
  6688. ""
  6689. "    private:"
  6690. ""
  6691. "    // ..."
  6692. "  };"
  6693. ""
  6694. ""
  6695. " Descripción de los métodos"
  6696. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6697. ""
  6698. "▄▄▄▄▄▄▄"
  6699. " flush    Función miembro"
  6700. "▀▀▀▀▀▀▀"
  6701. "┌─────────┬─────────────────────┐"
  6702. "│ ostream │ Vuelca el flujo:    │"
  6703. "│         │   ostream& flush () │"
  6704. "└─────────┴─────────────────────┘"
  6705. ""
  6706. "▄▄▄▄▄▄▄"
  6707. " seekp    Función miembro"
  6708. "▀▀▀▀▀▀▀"
  6709. "┌─────────┬─────────────────────────────────────────────────────────┐"
  6710. "│ ostream │ Mueve a una posición absoluta (normalmente el argumento │"
  6711. "│         │ es un valor devuelto por tellp):                        │"
  6712. "│         │   ostream& seekp (long)                                 │"
  6713. "│         ├─────────────────────────────────────────────────────────┤"
  6714. "│         │ Mueve a una posición relativa a la posición actual:     │"
  6715. "│         │   ostream& seekp (long, seek_dir)                       │"
  6716. "│         │                                                         │"
  6717. "│         │ Usa esta definición para seek_dir:                      │"
  6718. "│         │   enum seek_dir { beg, cur, end };                      │"
  6719. "└─────────┴─────────────────────────────────────────────────────────┘"
  6720. ""
  6721. "▄▄▄▄▄"
  6722. " put    Función miembro"
  6723. "▀▀▀▀▀"
  6724. "┌─────────┬────────────────────────┐"
  6725. "│ ostream │ Inserta el carácter:   │"
  6726. "│         │   ostream& put (char)  │"
  6727. "└─────────┴────────────────────────┘"
  6728. ""
  6729. "▄▄▄▄▄▄▄"
  6730. " tellp    Función miembro"
  6731. "▀▀▀▀▀▀▀"
  6732. "┌─────────┬────────────────────────────────────────┐"
  6733. "│ ostream │ Devuelve la posición actual del flujo: │"
  6734. "│         │   long tellp ()                        │"
  6735. "└─────────┴────────────────────────────────────────┘"
  6736. ""
  6737. "▄▄▄▄▄▄▄"
  6738. " write    Función miembro"
  6739. "▀▀▀▀▀▀▀"
  6740. "┌─────────┬────────────────────────────────────────────────┐"
  6741. "│ ostream │ Inserta n caracteres (incluido nulos):         │"
  6742. "│         │   ostream& write (const signed char*, int n)   │"
  6743. "│         │   ostream& write (const unsigned char*, int n) │"
  6744. "└─────────┴────────────────────────────────────────────────┘"
  6745. ""
  6746. ""
  6747. " Programa ejemplo"
  6748. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6749. ""
  6750. "// Este ejemplo prueba todos los métodos (funciones miembros) de la clase"
  6751. "// ostream."
  6752. ""
  6753. "/*"
  6754. "  Los ejemplos se realizarán sobre el flujo cout que está predefinido en"
  6755. "  iostream.h. El objeto cout no es del tipo ostream sino de un tipo derivado"
  6756. "  de la clase ostream y por este motivo puede hacer uso de los miembros"
  6757. "  públicos y protegidos de la clase ostream."
  6758. "*/"
  6759. ""
  6760. "#include <iostream.h>"
  6761. "#include <conio.h>"
  6762. "#include <string.h>"
  6763. ""
  6764. "void main (void)"
  6765. "{"
  6766. "  cout.flush () << "Volcando flujo.";"
  6767. ""
  6768. "  cout << "\nPosición actual en flujo cout leída, puesta y leída de nuevo: ""
  6769. "       << cout.seekp (cout.tellp ()).tellp ();"
  6770. ""
  6771. "  const char *p = "\nInsertando esta cadena y el carácter X.";"
  6772. "  const char lp = strlen (p);"
  6773. "  cout.write (p, lp - 1).put (p[lp - 1]) << "\n";"
  6774. ""
  6775. "  getch ();"
  6776. "}"
  6777. ""
  6778. "/*"
  6779. "SALIDA:"
  6780. ""
  6781. "«"
  6782. "Volcando flujo."
  6783. "Posición actual en flujo cout leída, puesta y leída de nuevo: 2090"
  6784. "Insertando esta cadena y el carácter X."
  6785. ""
  6786. "»"
  6787. ""
  6788. "OBSERVACIONES SOBRE LA SALIDA DEL PROGRAMA:"
  6789. ""
  6790. "1) El número 2090 es distinto en cada ejecución del programa. Las"
  6791. "funciones seekp() y tellp() son realmente útiles al leer ficheros"
  6792. "de discos."
  6793. "*/"
  6794. ""
  6795. endvis
  6796. beginvis
  6797. no_multiatributo
  6798. cabecera " CLASE iostream "
  6799. borde 2
  6800. coordenadas_completas 1 2 80 24
  6801. color 0 3
  6802. " ▄▄▄▄▄▄▄▄▄▄"
  6803. "  iostream   Permite entrada y salida sobre un flujo."
  6804. " ▀▀▀▀▀▀▀▀▀▀"
  6805. " ┌─────────┐                    ┌───────────┐"
  6806. " │ istream ├─┐  █▀▀▀▀▀▀▀▀▀▀█  ┌─┤ fstream   │"
  6807. " ╞═════════╡ ├──█ iostream █──┤ ╞═══════════╡"
  6808. " │ ostream ├─┘  █▄▄▄▄▄▄▄▄▄▄█  └─┤ strstream │"
  6809. " └─────────┘                    └───────────┘"
  6810. ""
  6811. "Declarada en: iostream.h"
  6812. ""
  6813. "La clase iostream es simplemente una mezcla de sus clases bases, permitiendo"
  6814. "entrada y salida sobre un flujo."
  6815. ""
  6816. ""
  6817. " Constructores"
  6818. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6819. "Asocia un streambuf dado con el flujo:"
  6820. "  iostream (streambuf *)"
  6821. ""
  6822. ""
  6823. " Funciones miembros"
  6824. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6825. " Ninguna"
  6826. ""
  6827. ""
  6828. " Definición"
  6829. " ▀▀▀▀▀▀▀▀▀▀"
  6830. ""
  6831. "class iostream : public istream, public ostream"
  6832. "  {"
  6833. "    public:"
  6834. ""
  6835. "    iostream (streambuf *);"
  6836. "    virtual ~iostream ();"
  6837. ""
  6838. "    protected:"
  6839. ""
  6840. "    iostream ();"
  6841. "  };"
  6842. ""
  6843. ""
  6844. " Programa ejemplo"
  6845. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6846. ""
  6847. "// Este ejemplo prueba algunos métodos (funciones miembros) de la clase"
  6848. "// iostream."
  6849. ""
  6850. "/*"
  6851. "  Los ejemplos se realizarán accediendo al streambuf de los flujos cout y"
  6852. "  cin a través de la función miembro rdbuf() de la clase ios. Esta función"
  6853. "  devuelve streambuf * y uno de los constructores de la clase iostream es"
  6854. "  precisamente de ese tipo. El objeto cout no es del tipo ios sino de un"
  6855. "  tipo derivado de la clase ios y por este motivo puede hacer uso de los"
  6856. "  miembros públicos y protegidos de la clase ios."
  6857. "*/"
  6858. ""
  6859. "#include <iostream.h>"
  6860. ""
  6861. "void main (void)"
  6862. "{"
  6863. "  int x;"
  6864. "  iostream ((iostream ((iostream (cout.rdbuf ()) << "Introduce x: ")"
  6865. "           .rdbuf ()) >> x).rdbuf ()) << "x es ";"
  6866. "  iostream ((iostream (cout.rdbuf ()) << x).rdbuf ()).flush ();"
  6867. "}"
  6868. ""
  6869. "/*"
  6870. "SALIDA:"
  6871. ""
  6872. "«"
  6873. "Introduce x: 5"
  6874. "x es 5"
  6875. "»"
  6876. ""
  6877. "OBSERVACIONES SOBRE LA SALIDA DEL PROGRAMA:"
  6878. ""
  6879. "1) El primer 5 de la salida mostrada es el número tecleado desde teclado"
  6880. "y visualizado en pantalla."
  6881. ""
  6882. "2) Los pasos que se realizan en la sentencia"
  6883. ""
  6884. "  iostream ((iostream ((iostream (cout.rdbuf ()) << "Introduce x: ")"
  6885. "           .rdbuf ()) >> x).rdbuf ()) << "x es ";"
  6886. ""
  6887. "son lo siguientes:"
  6888. ""
  6889. "Paso Expresión                                                Tipo de la expr"
  6890. "---- -------------------------------------------------------- ---------------"
  6891. ""
  6892. "1)   cout.rdbuf ()                                            streambuf *"
  6893. "2)   iostream (cout.rdbuf ())                                 iostream"
  6894. "3)   iostream (cout.rdbuf ()) << "Introduce x: "              ostream"
  6895. "4)   (iostream (cout.rdbuf ()) << "Introduce x: ").rdbuf ()   streambuf *"
  6896. "5)   iostream ((iostream (cout.rdbuf ()) << "Introduce x: ")"
  6897. "              .rdbuf ())                                      iostream"
  6898. "6)   iostream ((iostream (cout.rdbuf ()) << "Introduce x: ")"
  6899. "              .rdbuf ()) >> x                                 istream"
  6900. "6)   (iostream ((iostream (cout.rdbuf ()) << "Introduce x: ")"
  6901. "              .rdbuf ()) >> x).rdbuf ()                       streambuf *"
  6902. "7)   iostream ((iostream ((iostream (cout.rdbuf ())"
  6903. "              << "Introduce x: ").rdbuf ()) >> x).rdbuf ())   iostream"
  6904. "8)   iostream ((iostream ((iostream (cout.rdbuf ())"
  6905. "              << "Introduce x: ").rdbuf ()) >> x).rdbuf ())"
  6906. "              << "x es "                                      ostream"
  6907. "*/"
  6908. ""
  6909. endvis
  6910. beginvis
  6911. no_multiatributo
  6912. cabecera " CLASE istream_withassign "
  6913. borde 2
  6914. coordenadas_completas 1 2 80 24
  6915. color 0 3
  6916. " ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
  6917. "  istream_withassign    istream con un operador de asignación añadido"
  6918. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6919. " ┌─────────┐    █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█    ┌───────────┐"
  6920. " │ istream ├────█ istream_withassign █────┤ <ninguna> │"
  6921. " └─────────┘    █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█    └───────────┘"
  6922. ""
  6923. "Declarada en: iostream.h"
  6924. ""
  6925. ""
  6926. " Constructores"
  6927. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6928. "Constructor nulo (llama a constructor de istream):"
  6929. "  istream_withassign ()"
  6930. ""
  6931. ""
  6932. " Funciones miembros"
  6933. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6934. " Ninguna (Aunque el operador = está sobrecargado)"
  6935. ""
  6936. ""
  6937. " Definición"
  6938. " ▀▀▀▀▀▀▀▀▀▀"
  6939. ""
  6940. "class istream_withassign : public istream"
  6941. "  {"
  6942. "    public:"
  6943. ""
  6944. "    // no inicialización"
  6945. "    istream_withassign ();"
  6946. ""
  6947. "    virtual ~istream_withassign ();"
  6948. ""
  6949. "    // obtiene buffer de ostream y hace inicialización completa"
  6950. "    istream_withassign& operator= (istream&);"
  6951. ""
  6952. "    // asocia streambuf con flujo y hace inicialización completa"
  6953. "    istream_withassign& operator= (streambuf *);"
  6954. "  };"
  6955. ""
  6956. ""
  6957. " Programa ejemplo"
  6958. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  6959. ""
  6960. "// Este ejemplo prueba la clase istream_withassign"
  6961. ""
  6962. "/*"
  6963. "  El flujo cin es de tipo istream_withassign."
  6964. "*/"
  6965. ""
  6966. "#include <iostream.h>"
  6967. ""
  6968. "void main (void)"
  6969. "{"
  6970. "  const int longs = 256;"
  6971. "  char s[longs];"
  6972. ""
  6973. "  cout << "\nIntroduce cadena: ";"
  6974. "  cin >> s;"
  6975. "  cout << "\nCadena introducida: " << s;"
  6976. "  cout << "\nIntroduce línea: ";"
  6977. "  cin.getline (s, longs);"
  6978. "  cout << "\nLínea introducida: " << s;"
  6979. ""
  6980. "  cout << "\nIntroduce cadena saltando espacios blancos: ";"
  6981. "  cin.setf (ios::skipws);"
  6982. "  cin >> s;"
  6983. "  cout << "\nCadena introducida: " << s;"
  6984. "  while ((cin.rdbuf())->in_avail ()) // desecha caracteres que hay en buffer"
  6985. "    cin.get ();                      // para que próximo cin lea de teclado"
  6986. "  cout << "\nIntroduce cadena sin saltar espacios blancos: ";"
  6987. "  cin.unsetf (ios::skipws);"
  6988. "  cin >> s;"
  6989. "  cout << "\nCadena introducida: " << s;"
  6990. "}"
  6991. ""
  6992. "/*"
  6993. "SALIDA:"
  6994. ""
  6995. "«"
  6996. ""
  6997. "Introduce cadena: Antonio Lebrón Bocanegra"
  6998. ""
  6999. "Cadena introducida: Antonio"
  7000. "Introduce línea"
  7001. "Línea introducida:  Lebrón Bocanegra"
  7002. "Introduce cadena saltando espacios blancos:  x"
  7003. ""
  7004. "Cadena introducida: x"
  7005. "Introduce cadena sin saltar espacios blancos:  x"
  7006. ""
  7007. "Cadena introducida:"
  7008. "»"
  7009. ""
  7010. "OBSERVACIONES SOBRE LA SALIDA DEL PROGRAMA:"
  7011. ""
  7012. "1) Parte del texto mostrado en la salida anterior corresponde a texto"
  7013. "introducido por teclado y visualizado en pantalla. Esto se ve claramente"
  7014. "observando el código fuente. Por supuesto, tanto la salida como la"
  7015. "entrada se pueden redirigir puesto que cout y cin trabajan con la salida"
  7016. "y la entrada estándar."
  7017. ""
  7018. "2) La diferencia de usar cin >> s y de usar cin.getline () o cin.get ()"
  7019. "es que la primera versión para de leer cuando se encuentra un carácter"
  7020. "espacio (correspondiente a la macro isspace() definida en ctype.h), un"
  7021. "carácter de nueva línea o el carácter de fin de fichero, mientras que"
  7022. "las dos versiones anteriores paran de leer cuando nosotros queremos."
  7023. "También se puede observar que la función getline() lee los caracteres del"
  7024. "buffer y no del teclado pues se encuentra el texto " Lebrón Bocanegra""
  7025. "seguido de un carácter de nueva línea en el buffer."
  7026. ""
  7027. "3) En la segunda parte de la función main() hay algunos conceptos intere-"
  7028. "santes. El primero de ellos es que por defecto, el indicador ios::skipws"
  7029. "está puesto a 1, por lo tanto, la sentencia cin.setf (ios::skipws) del"
  7030. "programa es innecesaria. Cuando este indicador está a 1, todos los primeros"
  7031. "caracteres de espacios blancos en la entrada son saltados. Por ejemplo, en"
  7032. "la salida se ve que se introduce " x" mientras que se almacena "x" en la"
  7033. "cadena de caracteres s. Sin embargo, en la segunda lectura, con el indicador"
  7034. "ios::skipws puesto a 0, los caracteres iniciales blancos no son saltados, y"
  7035. "por lo tanto, al encontrarse en primer lugar con un espacio blanco (ASCII"
  7036. "32) para de leer y la cadena s queda vacía. También es importante significar"
  7037. "que en la primera lectura, no sólo se introduce en el buffer de entrada los"
  7038. "caracteres espacio blanco y x (" x") sino también un carácter de nueva línea;"
  7039. "por ello, se utilizar el bucle while, para desechar este caracter; el bucle"
  7040. "while también nos previene, por ejemplo, de la entrada " x y" desechando la"
  7041. "'y' y el carácter de nueva línea, ya que si no, la segunda lectura empezaría"
  7042. "leyendo el espacio blanco que hay entre la x y la y."
  7043. "*/"
  7044. ""
  7045. endvis
  7046. beginvis
  7047. no_multiatributo
  7048. cabecera " CLASE ostream_withassign "
  7049. borde 2
  7050. coordenadas_completas 1 2 80 24
  7051. color 0 3
  7052. " ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
  7053. "  ostream_withassign    ostream con un operador de asignación añadido"
  7054. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7055. " ┌─────────┐   █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█   ┌─────────┐"
  7056. " │ ostream ├───█ ostream_withassign █───┤<ninguna>│"
  7057. " └─────────┘   █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█   └─────────┘"
  7058. ""
  7059. "Declarada en: iostream.h"
  7060. ""
  7061. ""
  7062. " Constructores"
  7063. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7064. "Constructor nulo (llama a constructor de ostream):"
  7065. "  ostream_withassign ()"
  7066. ""
  7067. ""
  7068. " Funciones miembros"
  7069. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7070. " Ninguna (Aunque el operador = está sobrecargado)"
  7071. ""
  7072. ""
  7073. " Definición"
  7074. " ▀▀▀▀▀▀▀▀▀▀"
  7075. ""
  7076. "class ostream_withassign : public ostream"
  7077. "  {"
  7078. "    public:"
  7079. ""
  7080. "    // no inicialización"
  7081. "    ostream_withassign ();"
  7082. ""
  7083. "    virtual ~ostream_withassign ();"
  7084. ""
  7085. "    // obtiene buffer de istream y hace inicialización completa"
  7086. "    ostream_withassign& operator= (ostream&);"
  7087. ""
  7088. "    // asocia streambuf con flujo y hace inicialización completa"
  7089. "    ostream_withassign& operator= (streambuf *);"
  7090. "  };"
  7091. ""
  7092. ""
  7093. " Programa ejemplo"
  7094. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7095. ""
  7096. "// Este ejemplo prueba la clase ostream_withassign."
  7097. "// EN REALIDAD, ESTE EJEMPLO MUESTRA COMO SOBRECARGAR LOS OPERDORES >> Y <<"
  7098. "// EN UNA CLASE DEFINIDA POR EL USUARIO"
  7099. ""
  7100. "/*"
  7101. "  El flujo cout es de tipo istream_withassign."
  7102. "*/"
  7103. ""
  7104. "#include <iostream.h>"
  7105. ""
  7106. "class vect"
  7107. "  {"
  7108. "    private:"
  7109. "      int x, y;"
  7110. ""
  7111. "    public:"
  7112. "      vect (int i = 0, int j = 0) { asig (i, j); }"
  7113. "      void asig (int i, int j) { x = i; y = j; }"
  7114. ""
  7115. "      vect operator+ (void) { return *this; }"
  7116. "      vect operator- (void) { return vect (-x, -y); }"
  7117. ""
  7118. "      friend vect operator+ (vect v1, vect v2)"
  7119. "        { return vect (v1.x + v2.x, v1.y + v2.y); }"
  7120. "      friend vect operator- (vect v1, vect v2)"
  7121. "        { return v1 + -v2; }"
  7122. ""
  7123. "      friend ostream& operator<< (ostream& out, vect v)"
  7124. "        { return out << '[' << v.x << ',' << v.y << ']'; }"
  7125. ""
  7126. "      friend istream& operator>> (istream& in, vect& v)"
  7127. "        { return in >> '[' >> v.x >> ',' >> v.y >> ']'; }"
  7128. "  };"
  7129. ""
  7130. "void main (void)"
  7131. "{"
  7132. "  vect vec, vec1 (1, 2), vec2 (-3);"
  7133. ""
  7134. "  cout << "\nvec1 = " << vec1 << "  vec2 = " << vec2;"
  7135. "  cout << "\n+vec1 - vec2 = " << vec1 - vec2;"
  7136. ""
  7137. "  cout << "\nIntroduce vec en la forma [x,y]: ";"
  7138. "  cin >> vec;"
  7139. "  cout << "vec: " << vec;"
  7140. "}"
  7141. ""
  7142. "/*"
  7143. "SALIDA:"
  7144. ""
  7145. "«"
  7146. ""
  7147. "vec1 = [1,2]  vec2 = [-3,0]"
  7148. "+vec1 - vec2 = [4,2]"
  7149. "Introduce vec en la forma [x,y]: [4,5]"
  7150. "vec: [4,5]"
  7151. "»"
  7152. ""
  7153. "OBSERVACIONES SOBRE LA SALIDA DEL PROGRAMA:"
  7154. ""
  7155. "1) El primer [4,5] es introducido desde teclado y visualizado en pantalla."
  7156. ""
  7157. "2) La línea"
  7158. ""
  7159. "   cout << "vec: " << vec;"
  7160. ""
  7161. "es equivalente a la línea:"
  7162. ""
  7163. "  cout.operator<< ("vec: "); operator<< (cout, vec);"
  7164. ""
  7165. "La direrencia de las dos llamadas anteriores a operator<< viene dada porque"
  7166. "la primera es una función miembro (ver definición de clase ostream.h) y la"
  7167. "segunda es una función amiga (ver definición de la clase vect más arriba)."
  7168. ""
  7169. "Los operadores << y >> son dos operadores binarios que se pueden sobrecargar"
  7170. "al igual que los demás operadores sobrecargables. De hecho, los operadores"
  7171. "<< y >> ya están sobrecargados en las clases istream y ostream para los tipos"
  7172. "definidos por el sistema."
  7173. ""
  7174. "Cuando se hace:"
  7175. ""
  7176. "  cout << "a" << 'b';"
  7177. ""
  7178. "se está haciendo en realidad:"
  7179. ""
  7180. "  (cout.operator<<("a")).operator<<('b');"
  7181. "*/"
  7182. ""
  7183. endvis
  7184. beginvis
  7185. no_multiatributo
  7186. cabecera " CLASE iostream_withassign "
  7187. borde 2
  7188. coordenadas_completas 1 2 80 24
  7189. color 0 3
  7190. " ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
  7191. "  iostream_withassign    iostream con un operador de asignación añadido"
  7192. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7193. " ┌──────────┐    █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█    ┌───────────┐"
  7194. " │ iostream ├────█ iostream_withassign █────┤ <ninguna> │"
  7195. " └──────────┘    █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█    └───────────┘"
  7196. ""
  7197. ""
  7198. "Declarada en:  iostream.h"
  7199. ""
  7200. ""
  7201. " Constructores"
  7202. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7203. "Constructor nulo (llama a constructor de iostream):"
  7204. "  iostream_withassign ()"
  7205. ""
  7206. ""
  7207. " Funciones miembros"
  7208. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7209. " Ninguna (Aunque el operador = está sobrecargado)"
  7210. ""
  7211. ""
  7212. " Definición"
  7213. " ▀▀▀▀▀▀▀▀▀▀"
  7214. ""
  7215. "class iostream_withassign : public iostream"
  7216. "  {"
  7217. "    public:"
  7218. ""
  7219. "    // no inicialización"
  7220. "    iostream_withassign ();"
  7221. ""
  7222. "    virtual ~iostream_withassign ();"
  7223. ""
  7224. "    // obtiene buffer de stream y hace inicialización completa"
  7225. "    iostream_withassign& operator= (ios&);"
  7226. ""
  7227. "    // asocia streambuf con flujo y hace inicialización completa"
  7228. "    iostream_withassign& operator= (streambuf *);"
  7229. "  };"
  7230. ""
  7231. endvis
  7232. beginvis
  7233. no_multiatributo
  7234. cabecera " FICHERO iostream.h "
  7235. borde 2
  7236. coordenadas_completas 1 2 80 24
  7237. color 0 3
  7238. " ▄▄▄▄▄▄▄▄▄▄▄▄"
  7239. "  IOSTREAM.H"
  7240. " ▀▀▀▀▀▀▀▀▀▀▀▀"
  7241. "Declara los flujos básicos."
  7242. ""
  7243. "Reemplaza al viejo fichero de cabecera stream.h."
  7244. ""
  7245. " Incluye"
  7246. " ▀▀▀▀▀▀▀"
  7247. " mem.h"
  7248. ""
  7249. " Clases"
  7250. " ▀▀▀▀▀▀"
  7251. " ios                   iostream              iostream_withassign"
  7252. " istream               istream_withassign    ostream"
  7253. " ostream_withassign    streambuf"
  7254. ""
  7255. " Funciones"
  7256. " ▀▀▀▀▀▀▀▀▀"
  7257. " allocate      bad           base          blen          cerr"
  7258. " cin           clear         cout          dbp           dec"
  7259. " do_sgetn      do_snextc     do_sputn      doallocate    eback"
  7260. " ebuf          egptr         endl          ends          eof"
  7261. " epptr         fail          fill          flags         flush"
  7262. " gbump         gcount        get           getline       good"
  7263. " gptr          hex           ignore        in_avail      oct"
  7264. " out_waiting   overflow      pbackfail     pbase         pbump"
  7265. " peek          precision     put           putback       read"
  7266. " sbumpc        seekg         seekoff       seekp         seekpos"
  7267. " setb          setbuf        setf          setg          setp"
  7268. " setstate      sgetc         sgetn         skip          snextc"
  7269. " sputbackc     sputc         sputn         stossc        sync"
  7270. " tellg         tellp         tie           unbuffered    underflow"
  7271. " unsetf        width         write         ws"
  7272. ""
  7273. " Constantes, tipos de datos, y variables globales"
  7274. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7275. " adjustfield (const)   basefield (const)     floatfield (const)"
  7276. " io_state (enum)       open_mode (enum)      seek_dir (enum)"
  7277. " streamoff (typedef)   streampos (typedef)"
  7278. ""
  7279. " Operadores sobrecargados"
  7280. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7281. "    =    >>    <<"
  7282. ""
  7283. " Contenido (abreviado):"
  7284. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7285. "// ..."
  7286. ""
  7287. "#ifndef __IOSTREAM_H"
  7288. "#define __IOSTREAM_H"
  7289. ""
  7290. "#if !defined( __MEM_H )"
  7291. "#include <mem.h>    // obtiene memcpy y NULL"
  7292. "#endif"
  7293. ""
  7294. "// ..."
  7295. ""
  7296. "// Definición de EOF que debe coincidir con la que se hace en <stdio.h>"
  7297. "#define EOF (-1)"
  7298. ""
  7299. "// extrae un carácter de int i, asegurando que zapeof(EOF) != EOF"
  7300. "#define zapeof(i) ((unsigned char)(i))"
  7301. ""
  7302. "typedef long streampos;"
  7303. "typedef long streamoff;"
  7304. ""
  7305. "class streambuf;"
  7306. "class ostream;"
  7307. ""
  7308. "class ios"
  7309. "  {"
  7310. "    // ..."
  7311. "  };"
  7312. ""
  7313. "class streambuf"
  7314. "  {"
  7315. "    // ..."
  7316. "  };"
  7317. ""
  7318. "class istream : virtual public ios"
  7319. "  {"
  7320. "    // ..."
  7321. "  };"
  7322. ""
  7323. "class ostream : virtual public ios"
  7324. "  {"
  7325. "    // ..."
  7326. "  };"
  7327. ""
  7328. "class iostream : public istream, public ostream"
  7329. "  {"
  7330. "    // ..."
  7331. "  };"
  7332. ""
  7333. "class istream_withassign : public istream"
  7334. "  {"
  7335. "    // ..."
  7336. "  };"
  7337. ""
  7338. "class ostream_withassign : public ostream"
  7339. "  {"
  7340. "    // ..."
  7341. "  };"
  7342. ""
  7343. "class iostream_withassign : public iostream"
  7344. "  {"
  7345. "    // ..."
  7346. "  };"
  7347. ""
  7348. "/*"
  7349. " * Los flujos predefinidos"
  7350. " */"
  7351. "extern istream_withassign cin;"
  7352. "extern ostream_withassign cout;"
  7353. "extern ostream_withassign cerr;"
  7354. "extern ostream_withassign clog;"
  7355. ""
  7356. "/*"
  7357. " * Manipuladores"
  7358. " */"
  7359. "ostream& endl (ostream&);  // inserta nueva línea y vuelca"
  7360. "ostream& ends (ostream&);  // inserta nulo para terminar string"
  7361. "ostream& flush (ostream&); // vuelca el flujo"
  7362. "ios&     dec (ios&);       // pone base de conversión a decimal"
  7363. "ios&     hex (ios&);       // pone base de conversión a hexadecimal"
  7364. "ios&     oct (ios&);       // pone base de conversión a octal"
  7365. "istream& ws (istream&);    // extrae caracteres de espacios blancos"
  7366. ""
  7367. "#endif"
  7368. ""
  7369. ""
  7370. " Programa ejemplo"
  7371. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7372. ""
  7373. "// Ejemplo sobre manipuladores."
  7374. ""
  7375. "#include <iostream.h>"
  7376. ""
  7377. "inline ostream& may (ostream& out)"
  7378. "{"
  7379. "  return out.setf (ios::uppercase), out;"
  7380. "}"
  7381. ""
  7382. "inline ostream& dosendl (ostream& out)"
  7383. "{"
  7384. "  return out << endl << endl;"
  7385. "}"
  7386. ""
  7387. "void main (void)"
  7388. "{"
  7389. "  const int num = 10;"
  7390. "  const char sp = ' ';"
  7391. ""
  7392. "  cout << dec << 10 << sp << hex << num << sp << may << num << sp"
  7393. "       << oct << num << dosendl << flush;"
  7394. ""
  7395. "  int x;"
  7396. "  const char *msj = "Introduce valor de x: ";"
  7397. ""
  7398. "  cout << msj;"
  7399. "  cin >> ws >> x;"
  7400. "  cout << "El valor de x es: " << x << ends;"
  7401. "}"
  7402. ""
  7403. "/*"
  7404. "SALIDA:"
  7405. ""
  7406. "«"
  7407. "10 a A 12"
  7408. ""
  7409. "Introduce valor de x: 3"
  7410. "El valor de x es 3"
  7411. "»"
  7412. ""
  7413. "OBSERVACIONES SOBRE LA SALIDA DEL PROGRAMA:"
  7414. ""
  7415. "1) El primer 3 es introducido desde teclado y visualizado en pantalla."
  7416. ""
  7417. "2) Los manipuladores endl, ends, flush, dec, hex, oct y ws están declarados"
  7418. "en el fichero iostream.h. Los manipuladores may y dosendl son manipuladores"
  7419. "definidos por el usuario. El manipulador ends es útil cuando la salida se"
  7420. "dirige hacia un string en vez de a pantalla o a fichero."
  7421. "*/"
  7422. ""
  7423. endvis
  7424. partir
  7425. beginvis
  7426. no_multiatributo
  7427. cabecera " CLASE filebuf "
  7428. borde 2
  7429. coordenadas_completas 1 2 80 24
  7430. color 0 3
  7431. " ▄▄▄▄▄▄▄▄▄"
  7432. "  filebuf    Especializa streambuf para manipular ficheros."
  7433. " ▀▀▀▀▀▀▀▀▀"
  7434. " ┌───────────┐   █▀▀▀▀▀▀▀▀▀█   ┌───────────┐"
  7435. " │ streambuf ├───█ filebuf █───┤ <ninguna> │"
  7436. " └───────────┘   █▄▄▄▄▄▄▄▄▄█   └───────────┘"
  7437. ""
  7438. " Declarada en: fstream.h"
  7439. ""
  7440. ""
  7441. " Constructores"
  7442. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7443. "Crea un filebuf que no es añadido a un fichero:"
  7444. "  filebuf ()"
  7445. ""
  7446. "Crea un filebuf añadido a un fichero vía un descriptor de fichero:"
  7447. "  filebuf (int fd)"
  7448. ""
  7449. "Crea un filebuf añadido a un fichero y usa el buffer de n caracteres"
  7450. "especificado:"
  7451. "  filebuf (int fd, char *, int n)"
  7452. ""
  7453. ""
  7454. " Funciones miembros"
  7455. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7456. " attach    close     fd        is_open   open      seekoff   setbuf"
  7457. ""
  7458. ""
  7459. " Definición"
  7460. " ▀▀▀▀▀▀▀▀▀▀"
  7461. ""
  7462. "class  filebuf : public streambuf"
  7463. "  {"
  7464. "    public:"
  7465. ""
  7466. "    static const int openprot;  // protección del fichero por defecto"
  7467. ""
  7468. "    // constructores, destructor"
  7469. "    filebuf ();                    // crea un filebuf cerrado"
  7470. "    filebuf (int);                 // crea un filebuf añadido a fd"
  7471. "    filebuf (int _f, char *, int); // igual, con buffer especificado"
  7472. "    ~filebuf ();"
  7473. ""
  7474. "    int is_open ();   // está el fichero abierto"
  7475. "    int fd ();        // cuál es el descriptor del fichero"
  7476. ""
  7477. "    // abre fichero nombrado con modo y protección, lo añade a este filebuf"
  7478. "    filebuf * open (const char *, int, int = filebuf::openprot );"
  7479. ""
  7480. "    filebuf * close ();      // vuelca y cierra fichero"
  7481. "    filebuf * attach (int);  // añade este filbuf al descriptor de fichero"
  7482. "                             // abierto"
  7483. ""
  7484. "    /*"
  7485. "     * Ejecutan las funciones de streambuf sobre un filebuf"
  7486. "     * Los punteros de lectura y escritura son guardados juntos"
  7487. "     */"
  7488. "    virtual int overflow (int = EOF);"
  7489. "    virtual int underflow ();"
  7490. "    virtual int sync ();"
  7491. "    virtual streampos seekoff (streamoff, seek_dir, int);"
  7492. "    virtual streambuf * setbuf (char *, int);"
  7493. ""
  7494. "    protected:"
  7495. ""
  7496. "    // ..."
  7497. "  };"
  7498. ""
  7499. ""
  7500. " Descripción de los métodos"
  7501. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7502. ""
  7503. "▄▄▄▄▄▄▄▄"
  7504. " attach    Función miembro"
  7505. "▀▀▀▀▀▀▀▀"
  7506. "┌─────────────┬─────────────────────────────────────────────────────────────┐"
  7507. "│ filebuf     │ Añade este filebuf cerrado al descriptor de fichero abierto:│"
  7508. "│             │   filebuf* attach (int)                                     │"
  7509. "├─────────────┼─────────────────────────────────────────────────────────────┤"
  7510. "│ fstreambase │ Conecta a un descriptor de fichero abierto:                 │"
  7511. "│             │   void attach (int)                                         │"
  7512. "└─────────────┴─────────────────────────────────────────────────────────────┘"
  7513. ""
  7514. "▄▄▄▄▄▄▄"
  7515. " close    Función miembro"
  7516. "▀▀▀▀▀▀▀"
  7517. "┌─────────────┬──────────────────────────────────────────────────────────┐"
  7518. "│ filebuf     │ Vuelca y cierra el fichero. Devuelve 0 en caso de error: │"
  7519. "│             │   filebuf* close ()                                      │"
  7520. "├─────────────┼──────────────────────────────────────────────────────────┤"
  7521. "│ fstreambase │ Cierra el filebuf y fichero asociado:                    │"
  7522. "│             │   void close ()                                          │"
  7523. "└─────────────┴──────────────────────────────────────────────────────────┘"
  7524. ""
  7525. "▄▄▄▄"
  7526. " fd    Función miembro"
  7527. "▀▀▀▀"
  7528. "┌─────────┬──────────────────────────────────────────┐"
  7529. "│ filebuf │ Devuelve el descriptor de fichero o EOF: │"
  7530. "│         │   int fd ()                              │"
  7531. "└─────────┴──────────────────────────────────────────┘"
  7532. ""
  7533. "▄▄▄▄▄▄▄▄▄"
  7534. " is_open    Función miembro"
  7535. "▀▀▀▀▀▀▀▀▀"
  7536. "┌─────────┬────────────────────────────────────────────────────────────────┐"
  7537. "│ filebuf │ Devuelve un valor distinto de cero si el fichero está abierto: │"
  7538. "│         │   int is_open()                                                │"
  7539. "└─────────┴────────────────────────────────────────────────────────────────┘"
  7540. ""
  7541. "▄▄▄▄▄▄"
  7542. " open    Función miembro"
  7543. "▀▀▀▀▀▀"
  7544. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  7545. "│ filebuf     │ Abre el fichero dado y se conecta a él:                 │"
  7546. "│             │   filebuf* open (const char*, int mode,                 │"
  7547. "│             │     int prot = filebuf::openprot)                       │"
  7548. "├─────────────┼─────────────────────────────────────────────────────────┤"
  7549. "│ fstream     │ Abre un fichero para un fstream:                        │"
  7550. "│ fstreambase │ Abre un fichero para un fstreambase:                    │"
  7551. "│ ifstream    │ Abre un fichero para un ifstream:                       │"
  7552. "│ ofstream    │ Abre un fichero para un ofstream:                       │"
  7553. "│             │   void open (const char*, int, int = filebuf::openprot) │"
  7554. "└─────────────┴─────────────────────────────────────────────────────────┘"
  7555. ""
  7556. "▄▄▄▄▄▄▄▄▄"
  7557. " seekoff    Función miembro"
  7558. "▀▀▀▀▀▀▀▀▀"
  7559. "┌──────────────┬────────────────────────────────────────────────────────────┐"
  7560. "│ filebuf      │ Mueve el puntero de fichero relativo a la posición actual: │"
  7561. "│              │   virtual long seekoff (long, seek_dir, int)               │"
  7562. "├──────────────┼────────────────────────────────────────────────────────────┤"
  7563. "│ streambuf    │ Mueve el puntero de lectura y/o escritura (el tercer       │"
  7564. "│              │ argumento determina cuál o si son ambos) relativo a la     │"
  7565. "│              │ posición actual:                                           │"
  7566. "│              │   virtual long seekoff (long, seek_dir,                    │"
  7567. "│              │     int = (ios::in | ios::out))                            │"
  7568. "├──────────────┼────────────────────────────────────────────────────────────┤"
  7569. "│ strstreambuf │ Mueve el puntero relativo a la posición actual:            │"
  7570. "│              │   virtual long seekoff (long, seek_dir, int)               │"
  7571. "└──────────────┴────────────────────────────────────────────────────────────┘"
  7572. ""
  7573. "▄▄▄▄▄▄▄▄"
  7574. " setbuf    Función miembro"
  7575. "▀▀▀▀▀▀▀▀"
  7576. "┌──────────────┬─────────────────────────────────────────────────┐"
  7577. "│ filebuf      │ Especifica el buffer a usar:                    │"
  7578. "│ strstreambuf │   virtual streambuf* setbuf (char*, int)        │"
  7579. "├──────────────┼─────────────────────────────────────────────────┤"
  7580. "│ fstreambase  │ Usa un buffer especificado:                     │"
  7581. "│              │   void setbuf (char*, int)                      │"
  7582. "├──────────────┼─────────────────────────────────────────────────┤"
  7583. "│ streambuf    │ Conecta a un buffer dado:                       │"
  7584. "│              │   virtual streambuf* setbuf (signed char*, int) │"
  7585. "└──────────────┴─────────────────────────────────────────────────┘"
  7586. ""
  7587. ""
  7588. " Programa ejemplo"
  7589. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7590. ""
  7591. "// Ejemplo sobre la clase filebuf."
  7592. ""
  7593. "#include <iostream.h>"
  7594. "#include <fstream.h>"
  7595. ""
  7596. "void main (void)"
  7597. "{"
  7598. "  ofstream fich;"
  7599. ""
  7600. "  fich.open ("PRUEBA.TXT");"
  7601. ""
  7602. "  cout << "¿Está abierto?: " << (fich.rdbuf())->is_open() << endl"
  7603. "       << "Descriptor de fichero: " << (fich.rdbuf())->fd();"
  7604. ""
  7605. "  fich.close ();"
  7606. "}"
  7607. ""
  7608. "/*"
  7609. "SALIDA:"
  7610. ""
  7611. "«"
  7612. "¿Está abierto?: 1"
  7613. "Descriptor de fichero: 8"
  7614. "»"
  7615. ""
  7616. "OBSERVACIONES SOBRE LA SALIDA DEL PROGRAMA:"
  7617. ""
  7618. "1) El número del descriptor de fichero es dependiente del sistema."
  7619. ""
  7620. "2) La clase ofstream la veremos un poco más adelante. En este ejemplo, el"
  7621. "objeto fich es un fichero de escritura. La clase filebuf no se suele usar"
  7622. "directamente sino a través de sus clases derivadas tal y como hemos hecho"
  7623. "en este programa."
  7624. "*/"
  7625. ""
  7626. endvis
  7627. beginvis
  7628. no_multiatributo
  7629. cabecera " CLASE fstreambase "
  7630. borde 2
  7631. coordenadas_completas 1 2 80 24
  7632. color 0 3
  7633. " ▄▄▄▄▄▄▄▄▄▄▄▄▄"
  7634. "  fstreambase   Proporciona operaciones comunes a los flujos de fichero."
  7635. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7636. "                              ┌──────────┐"
  7637. "                            ┌─┤ fstream  │"
  7638. " ┌─────┐   █▀▀▀▀▀▀▀▀▀▀▀▀▀█──┘ ╞══════════╡"
  7639. " │ ios ├───█ fstreambase █────┤ ifstream │"
  7640. " └─────┘   █▄▄▄▄▄▄▄▄▄▄▄▄▄█──┐ ╞══════════╡"
  7641. "                            └─┤ ofstream │"
  7642. "                              └──────────┘"
  7643. "Declarada en: fstream.h"
  7644. ""
  7645. ""
  7646. " Constructores"
  7647. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7648. "Crea un fstreambase que no es añadido a un fichero:"
  7649. "  fstreambase ()"
  7650. ""
  7651. "Crea un fstreambase, abre un fichero, y lo conecta a él:"
  7652. "  fstreambase (const char*, int, int = filebuf::openprot)"
  7653. ""
  7654. "Crea un fstreambase, lo conecta a un descriptor de fichero abierto:"
  7655. "  fstreambase (int)"
  7656. ""
  7657. "Crea un fstreambase conectado a un fichero abierto, usa el buffer"
  7658. "especializado:"
  7659. "  fstreambase (int _f, char*, int)"
  7660. ""
  7661. ""
  7662. " Funciones miembros"
  7663. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7664. " attach   close    open     rdbuf    setbuf"
  7665. ""
  7666. ""
  7667. " Definición"
  7668. " ▀▀▀▀▀▀▀▀▀▀"
  7669. ""
  7670. "class fstreambase : virtual public ios"
  7671. "  {"
  7672. "    public:"
  7673. ""
  7674. "    fstreambase ();"
  7675. "    fstreambase (const char *, int, int = filebuf::openprot);"
  7676. "    fstreambase (int);"
  7677. "    fstreambase (int _f, char *, int);"
  7678. "    ~fstreambase ();"
  7679. ""
  7680. "    void open (const char *, int, int = filebuf::openprot);"
  7681. "    void attach (int);"
  7682. "    void close ();"
  7683. "    void setbuf (char *, int);"
  7684. "    filebuf * rdbuf ();"
  7685. ""
  7686. "    protected:"
  7687. ""
  7688. "    // ..."
  7689. ""
  7690. "    private:"
  7691. ""
  7692. "    // ..."
  7693. "  };"
  7694. ""
  7695. ""
  7696. " Descripción de los métodos"
  7697. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7698. ""
  7699. "▄▄▄▄▄▄▄▄"
  7700. " attach    Función miembro"
  7701. "▀▀▀▀▀▀▀▀"
  7702. "┌─────────────┬─────────────────────────────────────────────────────────────┐"
  7703. "│ filebuf     │ Añade este filebuf cerrado al descriptor de fichero abierto:│"
  7704. "│             │   filebuf* attach (int)                                     │"
  7705. "├─────────────┼─────────────────────────────────────────────────────────────┤"
  7706. "│ fstreambase │ Conecta a un descriptor de fichero abierto:                 │"
  7707. "│             │   void attach (int)                                         │"
  7708. "└─────────────┴─────────────────────────────────────────────────────────────┘"
  7709. ""
  7710. "▄▄▄▄▄▄▄"
  7711. " close    Función miembro"
  7712. "▀▀▀▀▀▀▀"
  7713. "┌─────────────┬──────────────────────────────────────────────────────────┐"
  7714. "│ filebuf     │ Vuelca y cierra el fichero. Devuelve 0 en caso de error: │"
  7715. "│             │   filebuf* close ()                                      │"
  7716. "├─────────────┼──────────────────────────────────────────────────────────┤"
  7717. "│ fstreambase │ Cierra el filebuf y fichero asociado:                    │"
  7718. "│             │   void close ()                                          │"
  7719. "└─────────────┴──────────────────────────────────────────────────────────┘"
  7720. ""
  7721. "▄▄▄▄▄▄"
  7722. " open    Función miembro"
  7723. "▀▀▀▀▀▀"
  7724. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  7725. "│ filebuf     │ Abre el fichero dado y se conecta a él:                 │"
  7726. "│             │   filebuf* open (const char*, int mode,                 │"
  7727. "│             │     int prot = filebuf::openprot)                       │"
  7728. "├─────────────┼─────────────────────────────────────────────────────────┤"
  7729. "│ fstream     │ Abre un fichero para un fstream:                        │"
  7730. "│ fstreambase │ Abre un fichero para un fstreambase:                    │"
  7731. "│ ifstream    │ Abre un fichero para un ifstream:                       │"
  7732. "│ ofstream    │ Abre un fichero para un ofstream:                       │"
  7733. "│             │   void open (const char*, int, int = filebuf::openprot) │"
  7734. "└─────────────┴─────────────────────────────────────────────────────────┘"
  7735. ""
  7736. "▄▄▄▄▄▄▄"
  7737. " rdbuf    Función miembro"
  7738. "▀▀▀▀▀▀▀"
  7739. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  7740. "│ ios         │ Devuelve un puntero al streambuf asignado a este flujo: │"
  7741. "│             │   streambuf* rdbuf ()                                   │"
  7742. "├─────────────┼─────────────────────────────────────────────────────────┤"
  7743. "│ fstream     │ Devuelve el buffer usado:                               │"
  7744. "│ fstreambase │   filebuf* rdbuf ()                                     │"
  7745. "│ ifstream    │                                                         │"
  7746. "│ ofstream    │                                                         │"
  7747. "└─────────────┴─────────────────────────────────────────────────────────┘"
  7748. ""
  7749. "▄▄▄▄▄▄▄▄"
  7750. " setbuf    Función miembro"
  7751. "▀▀▀▀▀▀▀▀"
  7752. "┌──────────────┬─────────────────────────────────────────────────┐"
  7753. "│ filebuf      │ Especifica el buffer a usar:                    │"
  7754. "│ strstreambuf │   virtual streambuf* setbuf (char*, int)        │"
  7755. "├──────────────┼─────────────────────────────────────────────────┤"
  7756. "│ fstreambase  │ Usa un buffer especificado:                     │"
  7757. "│              │   void setbuf (char*, int)                      │"
  7758. "├──────────────┼─────────────────────────────────────────────────┤"
  7759. "│ streambuf    │ Conecta a un buffer dado:                       │"
  7760. "│              │   virtual streambuf* setbuf (signed char*, int) │"
  7761. "└──────────────┴─────────────────────────────────────────────────┘"
  7762. ""
  7763. ""
  7764. " Programa ejemplo"
  7765. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7766. ""
  7767. "// Ejemplo sobre la clase fstreambase."
  7768. ""
  7769. "#include <iostream.h>"
  7770. "#include <fstream.h>"
  7771. ""
  7772. "void main (void)"
  7773. "{"
  7774. "  ofstream fich;"
  7775. ""
  7776. "  fich.open ("PRUEBA.TXT");"
  7777. ""
  7778. "  cout << (fich.rdbuf () == fich.fstreambase::rdbuf ());"
  7779. ""
  7780. "  fich.close ();"
  7781. "}"
  7782. ""
  7783. "/*"
  7784. "SALIDA:"
  7785. ""
  7786. "«"
  7787. "1"
  7788. "»"
  7789. ""
  7790. "OBSERVACIONES SOBRE EL PROGRAMA:"
  7791. ""
  7792. "1) La clase fstreambase es clase base de las clases ifstream, ofstream y"
  7793. "fstream. Esta clase base no se suele usar directamente sino que sirve"
  7794. "simplemente como clase base de las tres clases mencionadas."
  7795. ""
  7796. "2) La función ofstream::rdbuf() está implementada como una función inline"
  7797. "que lo único que hace es realizar la llamada fstreambase::rdbuf()."
  7798. "*/"
  7799. ""
  7800. endvis
  7801. beginvis
  7802. no_multiatributo
  7803. cabecera " CLASE ifstream "
  7804. borde 2
  7805. coordenadas_completas 1 2 80 24
  7806. color 0 3
  7807. " ▄▄▄▄▄▄▄▄▄▄"
  7808. "  ifstream   Proporciona operaciones de entrada sobre un filebuf."
  7809. " ▀▀▀▀▀▀▀▀▀▀"
  7810. " ┌─────────────┐"
  7811. " │ fstreambase ├──┐   █▀▀▀▀▀▀▀▀▀▀█    ┌───────────┐"
  7812. " ╞═════════════╡  ├───█ ifstream █────┤ <ninguna> │"
  7813. " │   istream   ├──┘   █▄▄▄▄▄▄▄▄▄▄█    └───────────┘"
  7814. " └─────────────┘"
  7815. ""
  7816. "Declarada en: fstream.h"
  7817. ""
  7818. ""
  7819. " Constructores"
  7820. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7821. "Crea un ifstream que no es añadido a un fichero:"
  7822. "  ifstream ()"
  7823. ""
  7824. "Crea un ifstream, abre un fichero, y lo conecta a él:"
  7825. "  ifstream (const char*, int, int = filebuf::openprot)"
  7826. ""
  7827. "Crea un ifstream, lo conecta a un descriptor de fichero abierto:"
  7828. "  ifstream(int)"
  7829. ""
  7830. "Crea un ifstream, conectado a un fichero abierto y usa un buffer"
  7831. "especificado:"
  7832. "  ifstream(int fd, char*, int)"
  7833. ""
  7834. " Funciones miembros"
  7835. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7836. " open    rdbuf"
  7837. ""
  7838. ""
  7839. " Definición"
  7840. " ▀▀▀▀▀▀▀▀▀▀"
  7841. ""
  7842. "class ifstream : public fstreambase, public istream"
  7843. "  {"
  7844. "    public:"
  7845. ""
  7846. "    ifstream ();"
  7847. "    ifstream (const char *, int = ios::in, int = filebuf::openprot);"
  7848. "    ifstream (int);"
  7849. "    ifstream (int _f, char *, int);"
  7850. "    ~ifstream ();"
  7851. ""
  7852. "    filebuf * rdbuf ();"
  7853. "    void open (const char *, int = ios::in, int = filebuf::openprot);"
  7854. "  };"
  7855. ""
  7856. ""
  7857. " Descripción de los métodos"
  7858. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7859. ""
  7860. "▄▄▄▄▄▄"
  7861. " open    Función miembro"
  7862. "▀▀▀▀▀▀"
  7863. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  7864. "│ filebuf     │ Abre el fichero dado y se conecta a él:                 │"
  7865. "│             │   filebuf* open (const char*, int mode,                 │"
  7866. "│             │     int prot = filebuf::openprot)                       │"
  7867. "├─────────────┼─────────────────────────────────────────────────────────┤"
  7868. "│ fstream     │ Abre un fichero para un fstream:                        │"
  7869. "│ fstreambase │ Abre un fichero para un fstreambase:                    │"
  7870. "│ ifstream    │ Abre un fichero para un ifstream:                       │"
  7871. "│ ofstream    │ Abre un fichero para un ofstream:                       │"
  7872. "│             │   void open (const char*, int, int = filebuf::openprot) │"
  7873. "└─────────────┴─────────────────────────────────────────────────────────┘"
  7874. ""
  7875. "▄▄▄▄▄▄▄"
  7876. " rdbuf    Función miembro"
  7877. "▀▀▀▀▀▀▀"
  7878. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  7879. "│ ios         │ Devuelve un puntero al streambuf asignado a este flujo: │"
  7880. "│             │   streambuf* rdbuf ()                                   │"
  7881. "├─────────────┼─────────────────────────────────────────────────────────┤"
  7882. "│ fstream     │ Devuelve el buffer usado:                               │"
  7883. "│ fstreambase │   filebuf* rdbuf ()                                     │"
  7884. "│ ifstream    │                                                         │"
  7885. "│ ofstream    │                                                         │"
  7886. "└─────────────┴─────────────────────────────────────────────────────────┘"
  7887. ""
  7888. ""
  7889. " Programa ejemplo"
  7890. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  7891. ""
  7892. "// Ejemplo sobre la clase ifstream."
  7893. ""
  7894. "#include <iostream.h>"
  7895. "#include <fstream.h>"
  7896. ""
  7897. "inline void error_apertura (const char *nomfich)"
  7898. "{"
  7899. "  cout << "No se puede abrir el fichero " << nomfich << endl;"
  7900. "}"
  7901. ""
  7902. "inline void error_cierre (const char *nomfich)"
  7903. "{"
  7904. "  cout << "No se puede cerrar el fichero " << nomfich << endl;"
  7905. "}"
  7906. ""
  7907. "void main (void)"
  7908. "{"
  7909. "  // APERTURAS DE FICHEROS DE TEXTO"
  7910. ""
  7911. "  // Forma 1 de abrir fichero:"
  7912. "  ifstream f1;"
  7913. "  f1.open ("FICH1.TXT");"
  7914. ""
  7915. "  // Forma 2 de abrir fichero:"
  7916. "  ifstream f2 ("FICH2.TXT");"
  7917. ""
  7918. "  // Forma 1 de comprobar apertura:"
  7919. "  if (f1.fail ()) // o también se puede hacer: if (! f1.good ())"
  7920. "    error_apertura ("FICH1.TXT");"
  7921. ""
  7922. "  // Forma 2 de comprobar apertura:"
  7923. "  if (! f2)"
  7924. "    error_apertura ("FICH2.TXT");"
  7925. ""
  7926. "  // APERTURA DE FICHERO BINARIO"
  7927. ""
  7928. "  ifstream f3 ("FICH3.TXT", ios::binary);"
  7929. "  if (! f3)"
  7930. "    error_apertura ("FICH3.TXT");"
  7931. ""
  7932. "  // CIERRE DE LOS FICHEROS ABIERTOS"
  7933. ""
  7934. "  f1.close ();"
  7935. "  if (! f1)"
  7936. "    error_cierre ("FICH1.TXT");"
  7937. "  f2.close ();"
  7938. "  if (! f2)"
  7939. "    error_cierre ("FICH2.TXT");"
  7940. "  f3.close ();"
  7941. "  if (! f3)"
  7942. "    error_cierre ("FICH3.TXT");"
  7943. "}"
  7944. ""
  7945. "/*"
  7946. "SALIDA:"
  7947. ""
  7948. "«"
  7949. "No se puede abrir el fichero FICH1.TXT"
  7950. "No se puede abrir el fichero FICH2.TXT"
  7951. "No se puede abrir el fichero FICH3.TXT"
  7952. "No se puede cerrar el fichero FICH1.TXT"
  7953. "No se puede cerrar el fichero FICH2.TXT"
  7954. "No se puede cerrar el fichero FICH3.TXT"
  7955. ""
  7956. "»"
  7957. ""
  7958. "OBSERVACIONES SOBRE EL PROGRAMA:"
  7959. ""
  7960. "1) Los errores se han producido al ejecutar este programa porque ninguno de"
  7961. "los tres ficheros de lectura (FICH1.TXT, FICH2.TXT y FICH3.TXT) existen en"
  7962. "disco."
  7963. ""
  7964. "2) Después de cada operación que se haga sobre un fichero se puede hacer la"
  7965. "comprobación de operación correcta. Ejemplo:"
  7966. "  ch = f1.get ();"
  7967. "  if (! f1)"
  7968. "    error ();"
  7969. ""
  7970. "Todas las funciones de la clase istream (y de sus clases bases como ios)"
  7971. "están a disposición de la clase ifstream. De esta forma, podemos leer del"
  7972. "fichero utilizando las funciones como get(), getline(), read() o el operador"
  7973. "sobrecargado >>."
  7974. ""
  7975. "Aunque el usuario no tiene porqué saber cómo están implementadas las funcio-"
  7976. "nes de una clase sino solamente su interface, diremos que el operador ! está"
  7977. "sobrecargado en la clase ios de la siguiente forma:"
  7978. ""
  7979. "inline int ios::operator! () { return fail (); }"
  7980. ""
  7981. "3) En la clase ifstream, si no se especifica el segundo parámetro de la fun-"
  7982. "ción open() o bien del constructor, éste es por defecto: ios::in."
  7983. ""
  7984. "4) Todo lo dicho en estas observaciones también se puede aplicar a la clase"
  7985. "ofstream que veremos a continuación, cambiando las funciones de lectura por"
  7986. "funciones de escritura y cambiando el modo de operación por defecto ios::in"
  7987. "al modo ios::out."
  7988. "*/"
  7989. ""
  7990. endvis
  7991. beginvis
  7992. no_multiatributo
  7993. cabecera " CLASE ofstream "
  7994. borde 2
  7995. coordenadas_completas 1 2 80 24
  7996. color 0 3
  7997. " ▄▄▄▄▄▄▄▄▄▄"
  7998. "  ofstream    Proporciona operaciones de salida sobre un filebuf."
  7999. " ▀▀▀▀▀▀▀▀▀▀"
  8000. " ┌─────────────┐"
  8001. " │ fstreambase ├──┐   █▀▀▀▀▀▀▀▀▀▀█   ┌───────────┐"
  8002. " ╞═════════════╡  ├───█ ofstream █───┤ <ninguna> │"
  8003. " │ ostream     ├──┘   █▄▄▄▄▄▄▄▄▄▄█   └───────────┘"
  8004. " └─────────────┘"
  8005. ""
  8006. "Declarada en: fstream.h"
  8007. ""
  8008. ""
  8009. " Constructores"
  8010. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8011. "Crea un ofstream que no es añadido a un fichero:"
  8012. "  ofstream ()"
  8013. ""
  8014. "Crea un ofstream, abre un fichero, y lo conecta a él:"
  8015. "  ofstream (const char*, int, int = filebuf::openprot)"
  8016. ""
  8017. "Crea un ifstream, lo conecta a un descriptor de fichero abierto:"
  8018. "  ofstream (int)"
  8019. ""
  8020. "Crea un ifstream, conectado a un fichero abierto y usa un buffer"
  8021. "especificado:"
  8022. "  ofstream (int fd, char*, int)"
  8023. ""
  8024. " Funciones miembros"
  8025. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8026. " open    rdbuf"
  8027. ""
  8028. ""
  8029. " Definición"
  8030. " ▀▀▀▀▀▀▀▀▀▀"
  8031. ""
  8032. "class ofstream : public fstreambase, public ostream"
  8033. "  {"
  8034. "    public:"
  8035. ""
  8036. "    ofstream ();"
  8037. "    ofstream (const char *, int = ios::out, int = filebuf::openprot);"
  8038. "    ofstream (int);"
  8039. "    ofstream (int _f, char *, int);"
  8040. "    ~ofstream ();"
  8041. ""
  8042. "    filebuf * rdbuf ();"
  8043. "    void open(const char *, int = ios::out, int = filebuf::openprot);"
  8044. "  };"
  8045. ""
  8046. ""
  8047. " Descripción de los métodos"
  8048. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8049. ""
  8050. "▄▄▄▄▄▄"
  8051. " open    Función miembro"
  8052. "▀▀▀▀▀▀"
  8053. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  8054. "│ filebuf     │ Abre el fichero dado y se conecta a él:                 │"
  8055. "│             │   filebuf* open (const char*, int mode,                 │"
  8056. "│             │     int prot = filebuf::openprot)                       │"
  8057. "├─────────────┼─────────────────────────────────────────────────────────┤"
  8058. "│ fstream     │ Abre un fichero para un fstream:                        │"
  8059. "│ fstreambase │ Abre un fichero para un fstreambase:                    │"
  8060. "│ ifstream    │ Abre un fichero para un ifstream:                       │"
  8061. "│ ofstream    │ Abre un fichero para un ofstream:                       │"
  8062. "│             │   void open (const char*, int, int = filebuf::openprot) │"
  8063. "└─────────────┴─────────────────────────────────────────────────────────┘"
  8064. ""
  8065. "▄▄▄▄▄▄▄"
  8066. " rdbuf    Función miembro"
  8067. "▀▀▀▀▀▀▀"
  8068. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  8069. "│ ios         │ Devuelve un puntero al streambuf asignado a este flujo: │"
  8070. "│             │   streambuf* rdbuf ()                                   │"
  8071. "├─────────────┼─────────────────────────────────────────────────────────┤"
  8072. "│ fstream     │ Devuelve el buffer usado:                               │"
  8073. "│ fstreambase │   filebuf* rdbuf ()                                     │"
  8074. "│ ifstream    │                                                         │"
  8075. "│ ofstream    │                                                         │"
  8076. "└─────────────┴─────────────────────────────────────────────────────────┘"
  8077. ""
  8078. ""
  8079. " Programa ejemplo"
  8080. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8081. ""
  8082. "// Ejemplo sobre la clase ofstream."
  8083. ""
  8084. "#include <iostream.h>"
  8085. "#include <fstream.h>"
  8086. ""
  8087. "inline void error_apertura (const char *nomfich)"
  8088. "{"
  8089. "  cout << "No se puede abrir el fichero " << nomfich << endl;"
  8090. "}"
  8091. ""
  8092. "void main (void)"
  8093. "{"
  8094. "  ofstream f1 ("FICH1.TXT");"
  8095. "  if (! f1)"
  8096. "    error_apertura ("FICH1.TXT");"
  8097. ""
  8098. "  ofstream f2 ("FICH2.TXT", ios::binary);"
  8099. "  if (! f2)"
  8100. "    error_apertura ("FICH2.TXT");"
  8101. ""
  8102. "  ofstream f3 ("FICH3.TXT", ios::app);"
  8103. "  if (! f3)"
  8104. "    error_apertura ("FICH3.TXT");"
  8105. ""
  8106. "  ofstream f4 ("FICH4.TXT", ios::app | ios::binary);"
  8107. "  if (! f4)"
  8108. "    error_apertura ("FICH4.TXT");"
  8109. ""
  8110. "  ofstream f5 ("FICH5.TXT", ios::nocreate);"
  8111. "  if (! f5)"
  8112. "    error_apertura ("FICH5.TXT");"
  8113. ""
  8114. "  ofstream f6 ("FICH6.TXT", ios::noreplace);"
  8115. "  if (! f6)"
  8116. "    error_apertura ("FICH6.TXT");"
  8117. ""
  8118. "  ofstream f7 ("FICH7.TXT", ios::nocreate | ios::noreplace);"
  8119. "  if (! f7)"
  8120. "    error_apertura ("FICH7.TXT");"
  8121. ""
  8122. "  ofstream f8 ("FICH8.TXT", ios::ate);"
  8123. "  if (! f8)"
  8124. "    error_apertura ("FICH8.TXT");"
  8125. ""
  8126. "  ofstream f9 ("FICH9.TXT", ios::trunc);"
  8127. "  if (! f9)"
  8128. "    error_apertura ("FICH9.TXT");"
  8129. ""
  8130. "  f1.close ();"
  8131. "  f2.close ();"
  8132. "  f3.close ();"
  8133. "  f4.close ();"
  8134. "  f5.close ();"
  8135. "  f6.close ();"
  8136. "  f7.close ();"
  8137. "  f8.close ();"
  8138. "  f9.close ();"
  8139. "}"
  8140. ""
  8141. "/*"
  8142. "SALIDA:"
  8143. ""
  8144. "«"
  8145. "No se puede abrir el fichero FICH5.TXT"
  8146. "No se puede abrir el fichero FICH7.TXT"
  8147. ""
  8148. "»"
  8149. ""
  8150. "OBSERVACIONES SOBRE EL PROGRAMA:"
  8151. ""
  8152. "1) Se ha producido error de apertura en FICH5.TXT porque éste no existe"
  8153. "en el disco. Sin embargo, con el fichero FICH7.TXT siempre se producirá"
  8154. "un error de apertura: si existe el fichero, hay error debido a ios::"
  8155. "noreplace, y si no existe el fichero, hay error debido a ios::nocreate."
  8156. "Por defecto, el fichero es abierto con modo de operación ios::out, esto"
  8157. "quiere decir, que tanto exista como no exista el fichero, se crea uno"
  8158. "nuevo; con los modos de operación se puede modificar esta situación. Lo"
  8159. "mismo ocurre con el modo texto que es el que está por defecto; para tra-"
  8160. "bajar con ficheros binarios, es necesario el indicador ios::binary. Con"
  8161. "el modo ios::app las escrituras en el fichero siempre se hacen al final"
  8162. "de éste; con el modo ios::ate se pueden hacer en cualquier lugar usando"
  8163. "el método seekp(). Si se abre el fichero con el modo ios::trunc se des-"
  8164. "carta el contenido actual del fichero si éste existe, o se crea un fi-"
  8165. "chero nuevo si no existe."
  8166. ""
  8167. "2) Podemos escribir en los ficheros abiertos anteriormente haciendo, por"
  8168. "ejemplo:"
  8169. "  f1 << 'x';"
  8170. "o utilizando los métodos de escritura tales como write() o put()."
  8171. "En resumen, podemos utilizar todas las funciones públicas de la clase"
  8172. "ostream, y por lo tanto, también de la clase ios. La otra clase base"
  8173. "de ostream es fstreambase."
  8174. "*/"
  8175. ""
  8176. endvis
  8177. beginvis
  8178. no_multiatributo
  8179. cabecera " CLASE fstream "
  8180. borde 2
  8181. coordenadas_completas 1 2 80 24
  8182. color 0 3
  8183. " ▄▄▄▄▄▄▄▄▄"
  8184. "  fstream   Proporciona entrada y salida simultánea sobre un filebuf."
  8185. " ▀▀▀▀▀▀▀▀▀"
  8186. " ┌─────────────┐"
  8187. " │ fstreambase ├──┐   █▀▀▀▀▀▀▀▀▀█   ┌───────────┐"
  8188. " ╞═════════════╡  ├───█ fstream █───┤ <ninguna> │"
  8189. " │  iostream   ├──┘   █▄▄▄▄▄▄▄▄▄█   └───────────┘"
  8190. " └─────────────┘"
  8191. ""
  8192. " Declarada en: fstream.h"
  8193. ""
  8194. " Constructores"
  8195. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8196. "Crea un fstream que no es añadido a un fichero:"
  8197. "  fstream ()"
  8198. ""
  8199. "Crea un fstream, abre un fichero, y lo conecta a él:"
  8200. "  fstream (const char*, int, int = filebuf::openprot)"
  8201. ""
  8202. "Crea un fstream, lo conecta a un descriptor de fichero abierto:"
  8203. "  fstream (int)"
  8204. ""
  8205. "Crea un fstream, conectado a un fichero abierto y usa un buffer especificado:"
  8206. "  fstream (int _f, char*, int)"
  8207. ""
  8208. ""
  8209. " Funciones miembros"
  8210. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8211. " open    rdbuf"
  8212. ""
  8213. ""
  8214. " Definición"
  8215. " ▀▀▀▀▀▀▀▀▀▀"
  8216. ""
  8217. "class fstream : public fstreambase, public iostream"
  8218. "  {"
  8219. "    public:"
  8220. ""
  8221. "    fstream ();"
  8222. "    fstream (const char *, int, int = filebuf::openprot);"
  8223. "    fstream (int);"
  8224. "    fstream (int _f, char *, int);"
  8225. "    ~fstream ();"
  8226. ""
  8227. "    filebuf * rdbuf ();"
  8228. "    void open (const char *, int, int = filebuf::openprot);"
  8229. "  };"
  8230. ""
  8231. ""
  8232. " Descripción de los métodos"
  8233. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8234. ""
  8235. "▄▄▄▄▄▄"
  8236. " open    Función miembro"
  8237. "▀▀▀▀▀▀"
  8238. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  8239. "│ filebuf     │ Abre el fichero dado y se conecta a él:                 │"
  8240. "│             │   filebuf* open (const char*, int mode,                 │"
  8241. "│             │     int prot = filebuf::openprot)                       │"
  8242. "├─────────────┼─────────────────────────────────────────────────────────┤"
  8243. "│ fstream     │ Abre un fichero para un fstream:                        │"
  8244. "│ fstreambase │ Abre un fichero para un fstreambase:                    │"
  8245. "│ ifstream    │ Abre un fichero para un ifstream:                       │"
  8246. "│ ofstream    │ Abre un fichero para un ofstream:                       │"
  8247. "│             │   void open (const char*, int, int = filebuf::openprot) │"
  8248. "└─────────────┴─────────────────────────────────────────────────────────┘"
  8249. ""
  8250. "▄▄▄▄▄▄▄"
  8251. " rdbuf    Función miembro"
  8252. "▀▀▀▀▀▀▀"
  8253. "┌─────────────┬─────────────────────────────────────────────────────────┐"
  8254. "│ ios         │ Devuelve un puntero al streambuf asignado a este flujo: │"
  8255. "│             │   streambuf* rdbuf ()                                   │"
  8256. "├─────────────┼─────────────────────────────────────────────────────────┤"
  8257. "│ fstream     │ Devuelve el buffer usado:                               │"
  8258. "│ fstreambase │   filebuf* rdbuf ()                                     │"
  8259. "│ ifstream    │                                                         │"
  8260. "│ ofstream    │                                                         │"
  8261. "└─────────────┴─────────────────────────────────────────────────────────┘"
  8262. ""
  8263. ""
  8264. " Programa ejemplo"
  8265. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8266. ""
  8267. "// Ejemplo sobre la clase fstream."
  8268. ""
  8269. "#include <iostream.h>"
  8270. "#include <fstream.h>"
  8271. ""
  8272. "inline void error_apertura (const char *nomfich)"
  8273. "{"
  8274. "  cout << "No se puede abrir el fichero " << nomfich << endl;"
  8275. "}"
  8276. ""
  8277. "void main (void)"
  8278. "{"
  8279. "  fstream f ("FICH.TXT", ios::in | ios::out);"
  8280. "  if (! f)"
  8281. "    error_apertura ("FICH.TXT");"
  8282. "  f.close ();"
  8283. "}"
  8284. ""
  8285. "/*"
  8286. "SALIDA:"
  8287. ""
  8288. "«"
  8289. "»"
  8290. ""
  8291. "OBSERVACIONES SOBRE EL PROGRAMA:"
  8292. ""
  8293. "1) Este programa no escribe nada porque no se produce error de apertura."
  8294. ""
  8295. "2) La clase fstream se suele utilizar para trabajar con ficheros de lectura"
  8296. "y escritura."
  8297. ""
  8298. "3) Por supuesto, se pueden añadir todos los indicadores de modos de opera-"
  8299. "ción que se deseen, tales como ios::nocreate para que la operación de aper-"
  8300. "tura falle si el fichero no existe, o ios::binary para abrir un fichero bi-"
  8301. "nario puesto que por defecto se abre el fichero en modo texto, o ios::nore-"
  8302. "place para que la operación de apertura falle si el fichero ya existe, etc."
  8303. "*/"
  8304. ""
  8305. endvis
  8306. beginvis
  8307. no_multiatributo
  8308. cabecera " FICHERO fstream.h "
  8309. borde 2
  8310. coordenadas_completas 1 2 80 24
  8311. color 0 3
  8312. " ▄▄▄▄▄▄▄▄▄▄▄"
  8313. "  FSTREAM.H"
  8314. " ▀▀▀▀▀▀▀▀▀▀▀"
  8315. "Declara las clases de flujos de C++ que soportan entrada y salida de"
  8316. "ficheros."
  8317. ""
  8318. " Incluye"
  8319. " ▀▀▀▀▀▀▀"
  8320. " iostream.h"
  8321. ""
  8322. " Clases"
  8323. " ▀▀▀▀▀▀"
  8324. " filebuf        fstream        fstreambase    ifstream       ofstream"
  8325. ""
  8326. " Constantes, tipos de datos, y variables globales"
  8327. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8328. " _FSTREAM_H_"
  8329. ""
  8330. ""
  8331. " Contenido (abreviado):"
  8332. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8333. ""
  8334. "#ifndef __FSTREAM_H"
  8335. "#define __FSTREAM_H"
  8336. ""
  8337. "#if !defined( __IOSTREAM_H )"
  8338. "#include <iostream.h>"
  8339. "#endif"
  8340. ""
  8341. "class filebuf : public streambuf"
  8342. "  {"
  8343. "    // ..."
  8344. "  };"
  8345. ""
  8346. "class fstreambase : virtual public ios"
  8347. "  {"
  8348. "    // ..."
  8349. "  };"
  8350. ""
  8351. "class ifstream : public fstreambase, public istream"
  8352. "  {"
  8353. "    // ..."
  8354. "  };"
  8355. ""
  8356. "class ofstream : public fstreambase, public ostream"
  8357. "  {"
  8358. "    // ..."
  8359. "  };"
  8360. ""
  8361. "class fstream : public fstreambase, public iostream"
  8362. "  {"
  8363. "    // ..."
  8364. "  };"
  8365. ""
  8366. "#endif"
  8367. ""
  8368. ""
  8369. " Programa ejemplo"
  8370. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8371. ""
  8372. "En el segundo ejemplo que se encuentra en la tarea de ejemplos de esta"
  8373. "lección se encuentra un programa bastante instructivo que hace uso de"
  8374. "las clases ifstream y ofstream: programa que copia un fichero en otro"
  8375. "sitio del disco."
  8376. ""
  8377. endvis
  8378. beginvis
  8379. no_multiatributo
  8380. cabecera " CLASE strstreambuf "
  8381. borde 2
  8382. coordenadas_completas 1 2 80 24
  8383. color 0 3
  8384. " ▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
  8385. "  strstreambuf    Especializa streambuf para formatos en memoria."
  8386. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8387. " ┌───────────┐   █▀▀▀▀▀▀▀▀▀▀▀▀▀▀█   ┌───────────┐"
  8388. " │ streambuf ├───█ strstreambuf █───┤ <ninguna> │"
  8389. " └───────────┘   █▄▄▄▄▄▄▄▄▄▄▄▄▄▄█   └───────────┘"
  8390. ""
  8391. "Declarada en: strstrea.h"
  8392. ""
  8393. ""
  8394. " Constructores"
  8395. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8396. "Crea un strstreambuf dinámico:"
  8397. "  strstreambuf ()"
  8398. ""
  8399. "  Será asignada memoria dinámicamente conforme sea necesaria."
  8400. ""
  8401. "Crea un buffer dinámico con funciones de asignación y liberación"
  8402. "especificadas."
  8403. "  strstreambuf (void * (*)(long), void * (*)(void *))"
  8404. ""
  8405. "Crea un strstreambuf dinámico, inicialmente se asigna un buffer de n bytes"
  8406. "como mínimo:"
  8407. "  strstreambuf (int n)"
  8408. ""
  8409. "Crea un strstreambuf estático con un buffer especificado:"
  8410. "  strstreambuf (char *, int, char *end)"
  8411. ""
  8412. "  Si en no es nulo, él delimita el buffer."
  8413. ""
  8414. ""
  8415. " Funciones miembros"
  8416. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8417. " freeze    str       setbuf    seekoff"
  8418. ""
  8419. ""
  8420. " Definición"
  8421. " ▀▀▀▀▀▀▀▀▀▀"
  8422. ""
  8423. "class strstreambuf : public streambuf"
  8424. "  {"
  8425. "    public:"
  8426. ""
  8427. "    strstreambuf ();"
  8428. "    strstreambuf (int n);"
  8429. "    strstreambuf (void * (*a) (long), void (*f) (void *));"
  8430. "    strstreambuf (signed char * _s, int, signed char * _strt = 0);"
  8431. "    strstreambuf (unsigned char * _s, int, unsigned char * _strt = 0);"
  8432. "    ~strstreambuf ();"
  8433. ""
  8434. "    void freeze (int = 1);"
  8435. "    char * str ();"
  8436. "    virtual int doallocate ();"
  8437. "    virtual int overflow (int);"
  8438. "    virtual int underflow ();"
  8439. "    virtual streambuf * setbuf (char *, int);"
  8440. "    virtual streampos seekoff (streamoff, seek_dir, int);"
  8441. ""
  8442. "    private:"
  8443. ""
  8444. "    // ..."
  8445. "  };"
  8446. ""
  8447. ""
  8448. " Descripción de los métodos"
  8449. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8450. ""
  8451. "▄▄▄▄▄▄▄▄"
  8452. " freeze    Función miembro"
  8453. "▀▀▀▀▀▀▀▀"
  8454. "┌──────────────┬────────────────────────────────────────────────────────────┐"
  8455. "│ strstreambuf │ Si el parámetro de entrada es distinto de cero, no permite │"
  8456. "│              │ almacenar caracteres en el buffer; realiza la operación    │"
  8457. "│              │ contraria pasando un cero:                                 │"
  8458. "│              │   void freeze (int = 1)                                    │"
  8459. "└──────────────┴────────────────────────────────────────────────────────────┘"
  8460. ""
  8461. "▄▄▄▄▄"
  8462. " str    Función miembro"
  8463. "▀▀▀▀▀"
  8464. "┌──────────────┬──────────────────────────────────────────────────────┐"
  8465. "│ ostrstream   │ Devuelve y congela (freeze) el buffer:               │"
  8466. "│ strstream    │   char *str ()                                       │"
  8467. "│              │ Debes liberar el buffer si es dinámico.              │"
  8468. "├──────────────┼──────────────────────────────────────────────────────┤"
  8469. "│ strstreambuf │ Devuelve un puntero al buffer y lo congela (freeze): │"
  8470. "│              │   char *str ()                                       │"
  8471. "└──────────────┴──────────────────────────────────────────────────────┘"
  8472. ""
  8473. "▄▄▄▄▄▄▄▄"
  8474. " setbuf    Función miembro"
  8475. "▀▀▀▀▀▀▀▀"
  8476. "┌──────────────┬─────────────────────────────────────────────────┐"
  8477. "│ filebuf      │ Especifica el buffer a usar:                    │"
  8478. "│ strstreambuf │   virtual streambuf* setbuf (char*, int)        │"
  8479. "├──────────────┼─────────────────────────────────────────────────┤"
  8480. "│ fstreambase  │ Usa un buffer especificado:                     │"
  8481. "│              │   void setbuf (char*, int)                      │"
  8482. "├──────────────┼─────────────────────────────────────────────────┤"
  8483. "│ streambuf    │ Conecta a un buffer dado:                       │"
  8484. "│              │   virtual streambuf* setbuf (signed char*, int) │"
  8485. "└──────────────┴─────────────────────────────────────────────────┘"
  8486. ""
  8487. "▄▄▄▄▄▄▄▄▄"
  8488. " seekoff    Función miembro"
  8489. "▀▀▀▀▀▀▀▀▀"
  8490. "┌──────────────┬────────────────────────────────────────────────────────────┐"
  8491. "│ filebuf      │ Mueve el puntero de fichero relativo a la posición actual: │"
  8492. "│              │   virtual long seekoff (long, seek_dir, int)               │"
  8493. "├──────────────┼────────────────────────────────────────────────────────────┤"
  8494. "│ streambuf    │ Mueve el puntero de lectura y/o escritura (el tercer       │"
  8495. "│              │ argumento determina cuál de los dos o ambos) relativo      │"
  8496. "│              │ a la posición actual:                                      │"
  8497. "│              │   virtual long seekoff (long, seek_dir,                    │"
  8498. "│              │     int = (ios::in | ios::out))                            │"
  8499. "├──────────────┼────────────────────────────────────────────────────────────┤"
  8500. "│ strstreambuf │ Mueve el puntero relativo a la posición actual:            │"
  8501. "│              │   virtual long seekoff(long, seek_dir, int)                │"
  8502. "└──────────────┴────────────────────────────────────────────────────────────┘"
  8503. ""
  8504. ""
  8505. " Programa ejemplo"
  8506. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8507. ""
  8508. "// Ejemplo sobre la clase strstreambuf."
  8509. ""
  8510. "#include <iostream.h>"
  8511. "#include <strstream.h>"
  8512. ""
  8513. "void main (void)"
  8514. "{"
  8515. "  const int tam = 100;"
  8516. "  char buf[tam];"
  8517. "  ostrstream s (buf, tam);"
  8518. ""
  8519. "  s << "abc" << ends;"
  8520. ""
  8521. "  cout << buf << ' '<< (s.rdbuf())->str();"
  8522. "}"
  8523. ""
  8524. "/*"
  8525. "SALIDA:"
  8526. ""
  8527. "«"
  8528. "abc abc"
  8529. "»"
  8530. ""
  8531. "OBSERVACIONES SOBRE EL PROGRAMA:"
  8532. ""
  8533. "1) La clase ostrstream se explicará un poco más adelante pero era necesario"
  8534. "utilizarla aquí puesto que la clase strstreambuf no se suele utilizar direc-"
  8535. "tamente."
  8536. ""
  8537. "2) El método str() que se ejecuta es el de la clase strstreambuf. Como se"
  8538. "verá más adelante, este método lo posee la clase ostrstream, con lo cual"
  8539. "se podía haber hecho directamente: s.str(). Aunque la forma más fácil de"
  8540. "acceder al buffer es utilizando directamente el mismo buffer si se dispone"
  8541. "de él como es éste el caso: buf."
  8542. ""
  8543. "3) El manipulador ends es necesario, ya que si no se hace, no hay carácter"
  8544. "nulo en buf que delimite el final de la cadena de caracteres."
  8545. "*/"
  8546. ""
  8547. endvis
  8548. beginvis
  8549. no_multiatributo
  8550. cabecera " CLASE strstreambase "
  8551. borde 2
  8552. coordenadas_completas 1 2 80 24
  8553. color 0 3
  8554. " ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"
  8555. "  strstreambase    Especializa ios para flujos de strings."
  8556. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8557. "                                ┌────────────┐"
  8558. "                              ┌─┤ istrstream │"
  8559. " ┌─────┐   █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█  │ ╞════════════╡"
  8560. " │ ios ├───█ strstreambase █──┼─┤ ostrstream │"
  8561. " └─────┘   █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█  │ ╞════════════╡"
  8562. "                              └─┤ strstream  │"
  8563. "                                └────────────┘"
  8564. "Declarada en: strstrea.h"
  8565. ""
  8566. ""
  8567. " Constructores"
  8568. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8569. "Crea un strstreambase vacío:"
  8570. "  strstreambase ()"
  8571. ""
  8572. "Crea un strstreambase con un buffer y posición de comienzo especificados:"
  8573. "  strstreambase (const char*, int, char *start)"
  8574. ""
  8575. ""
  8576. " Funciones miembros"
  8577. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8578. " Ninguna (usa ios)"
  8579. ""
  8580. ""
  8581. " Definición"
  8582. " ▀▀▀▀▀▀▀▀▀▀"
  8583. ""
  8584. "class strstreambase : public virtual ios"
  8585. "  {"
  8586. "    public:"
  8587. ""
  8588. "    strstreambuf * rdbuf ();"
  8589. ""
  8590. "    protected:"
  8591. ""
  8592. "    strstreambase (char *, int, char *);"
  8593. "    strstreambase ();"
  8594. "    ~strstreambase ();"
  8595. ""
  8596. "    private:"
  8597. ""
  8598. "    strstreambuf buf;"
  8599. "  };"
  8600. ""
  8601. ""
  8602. " Programa ejemplo"
  8603. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8604. ""
  8605. "// Ejemplo sobre la clase strstreambase."
  8606. ""
  8607. "#include <iostream.h>"
  8608. "#include <strstream.h>"
  8609. ""
  8610. "void main (void)"
  8611. "{"
  8612. "  const int tam = 100;"
  8613. "  char buf[tam];"
  8614. "  ostrstream s (buf, tam);"
  8615. ""
  8616. "  s << "abc" << ends;"
  8617. ""
  8618. "  cout << buf << ' '<< (s.strstreambase::rdbuf())->str();"
  8619. "}"
  8620. ""
  8621. "/*"
  8622. "SALIDA:"
  8623. ""
  8624. "«"
  8625. "abc abc"
  8626. "»"
  8627. ""
  8628. "OBSERVACIONES SOBRE EL PROGRAMA:"
  8629. ""
  8630. "1) La clase ostrstream se explicará un poco más adelante pero era necesario"
  8631. "utilizarla aquí puesto que la clase strstreambase no se suele utilizar"
  8632. "directamente sino como clase base de las clases istrstream, ostrstream y"
  8633. "strstream."
  8634. ""
  8635. "2) El método rdbuf() que se ejecuta es el de la clase strstreambase. Como"
  8636. "se verá más adelante, este método lo posee la clase ostrstream, con lo cual"
  8637. "se podía haber hecho directamente: s.rdbuf()."
  8638. "*/"
  8639. ""
  8640. endvis
  8641. beginvis
  8642. no_multiatributo
  8643. cabecera " CLASE istrstream "
  8644. borde 2
  8645. coordenadas_completas 1 2 80 24
  8646. color 0 3
  8647. " ▄▄▄▄▄▄▄▄▄▄▄▄"
  8648. "  istrstream    Proporciona operaciones de entrada sobre un strstreambuf."
  8649. " ▀▀▀▀▀▀▀▀▀▀▀▀"
  8650. " ┌───────────────┐"
  8651. " │ strstreambase ├──┐   █▀▀▀▀▀▀▀▀▀▀▀▀█   ┌───────────┐"
  8652. " ╞═══════════════╡  ├───█ istrstream █───┤ <ninguna> │"
  8653. " │ istream       ├──┘   █▄▄▄▄▄▄▄▄▄▄▄▄█   └───────────┘"
  8654. " └───────────────┘"
  8655. ""
  8656. "Declarada en: strstrea.h"
  8657. ""
  8658. ""
  8659. " Constructores"
  8660. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8661. "Crea un istrstream con un string especificado (el carácter nulo nunca se"
  8662. "extrae):"
  8663. "  istrstream (const char *)"
  8664. ""
  8665. "Crea un istrstream usando n bytes de un string especificado:"
  8666. "  istrstream (const char *, int n)"
  8667. ""
  8668. ""
  8669. " Funciones miembros"
  8670. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8671. " Ninguna"
  8672. ""
  8673. ""
  8674. " Definición"
  8675. " ▀▀▀▀▀▀▀▀▀▀"
  8676. ""
  8677. "class istrstream : public strstreambase, public istream"
  8678. "  {"
  8679. "    public:"
  8680. ""
  8681. "    istrstream (char *);"
  8682. "    istrstream (char *, int);"
  8683. "    ~istrstream ();"
  8684. "  };"
  8685. ""
  8686. ""
  8687. " Programa ejemplo"
  8688. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8689. ""
  8690. "// Ejemplo sobre la clase istrstream."
  8691. ""
  8692. "#include <iostream.h>"
  8693. "#include <strstream.h>"
  8694. "#include <stdlib.h>"
  8695. ""
  8696. "inline void error (const char *nomclase)"
  8697. "{"
  8698. "  cerr << "Error en clase " << nomclase;"
  8699. "  exit (1);"
  8700. "}"
  8701. ""
  8702. "void main (void)"
  8703. "{"
  8704. "  char *buf = "Ejemplo de la clase istrstream.";"
  8705. ""
  8706. "  istrstream s1 (buf);"
  8707. "  if (! s1)"
  8708. "    error ("s1");"
  8709. ""
  8710. "  istrstream s2 (buf, 5);"
  8711. "  if (! s2)"
  8712. "    error ("s2");"
  8713. ""
  8714. "  char ch, str[20];"
  8715. ""
  8716. "  s1 >> ch >> str;"
  8717. "  cout << ch << str << endl;"
  8718. ""
  8719. "  s2 >> ch >> str;"
  8720. "  cout << ch << str << endl;"
  8721. "}"
  8722. ""
  8723. "/*"
  8724. "SALIDA:"
  8725. ""
  8726. "«"
  8727. "Ejemplo"
  8728. "Ejemp"
  8729. "»"
  8730. ""
  8731. "OBSERVACIONES SOBRE EL PROGRAMA:"
  8732. ""
  8733. "1) Con la clase istrstream se trabaja de una forma similar que con la clase"
  8734. "ifstream, con la diferencia de que en istrstream se lee de un string y en"
  8735. "ifstream se lee de un fichero."
  8736. "*/"
  8737. ""
  8738. endvis
  8739. beginvis
  8740. no_multiatributo
  8741. cabecera " CLASE ostrstream "
  8742. borde 2
  8743. coordenadas_completas 1 2 80 24
  8744. color 0 3
  8745. " ▄▄▄▄▄▄▄▄▄▄▄▄"
  8746. "  ostrstream    Proporciona operaciones de salida sobre un strstreambuf."
  8747. " ▀▀▀▀▀▀▀▀▀▀▀▀"
  8748. " ┌───────────────┐"
  8749. " │ strstreambase ├──┐   █▀▀▀▀▀▀▀▀▀▀▀▀█   ┌───────────┐"
  8750. " ╞═══════════════╡  ├───█ istrstream █───┤ <ninguna> │"
  8751. " │ istream       ├──┘   █▄▄▄▄▄▄▄▄▄▄▄▄█   └───────────┘"
  8752. " └───────────────┘"
  8753. ""
  8754. "Declarada en: strstrea.h"
  8755. ""
  8756. ""
  8757. " Constructors"
  8758. " ▀▀▀▀▀▀▀▀▀▀▀▀"
  8759. "Crea un ostrstream dinámico:"
  8760. "  ostrstream ()"
  8761. ""
  8762. "Crea un ostrstream con un buffer de n bytes especificado:"
  8763. "  ostrstream (char*, int, int)"
  8764. ""
  8765. "  Si el modo es ios::app o ios::ate, el puntero de lectura/escritura"
  8766. "  es posicionado en el carácter nul del string."
  8767. ""
  8768. ""
  8769. " Funciones miembros"
  8770. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8771. " pcount   str"
  8772. ""
  8773. ""
  8774. " Definición"
  8775. " ▀▀▀▀▀▀▀▀▀▀"
  8776. ""
  8777. "class ostrstream : public strstreambase, public ostream"
  8778. "  {"
  8779. "    public:"
  8780. ""
  8781. "    ostrstream (char *, int, int = ios::out);"
  8782. "    ostrstream ();"
  8783. "    ~ostrstream ();"
  8784. ""
  8785. "    char * str ();"
  8786. "    int pcount ();"
  8787. "  };"
  8788. ""
  8789. ""
  8790. " Descripción de los métodos"
  8791. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8792. ""
  8793. "▄▄▄▄▄▄▄▄"
  8794. " pcount    Función miembro"
  8795. "▀▀▀▀▀▀▀▀"
  8796. "┌────────────┬────────────────────────────────────────────────────────────┐"
  8797. "│ ostrstream │ Devuelve el número de bytes almacenados actualmente en el  │"
  8798. "│            │ buffer:                                                    │"
  8799. "│            │   char *pcount ()                                          │"
  8800. "└────────────┴────────────────────────────────────────────────────────────┘"
  8801. ""
  8802. "▄▄▄▄▄"
  8803. " str    Función miembro"
  8804. "▀▀▀▀▀"
  8805. "┌──────────────┬──────────────────────────────────────────────────────┐"
  8806. "│ ostrstream   │ Devuelve y congela (freeze) el buffer:               │"
  8807. "│ strstream    │   char *str ()                                       │"
  8808. "│              │ Debes liberar el buffer si es dinámico.              │"
  8809. "├──────────────┼──────────────────────────────────────────────────────┤"
  8810. "│ strstreambuf │ Devuelve un puntero al buffer y lo congela (freeze): │"
  8811. "│              │   char *str ()                                       │"
  8812. "└──────────────┴──────────────────────────────────────────────────────┘"
  8813. ""
  8814. ""
  8815. " Programa ejemplo"
  8816. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8817. ""
  8818. "// Ejemplo sobre la clase ostrstream."
  8819. ""
  8820. "#include <iostream.h>"
  8821. "#include <strstream.h>"
  8822. "#include <stdlib.h>"
  8823. "#include <string.h>"
  8824. ""
  8825. "inline void error (const char *nomclase)"
  8826. "{"
  8827. "  cerr << "Error en clase " << nomclase;"
  8828. "  exit (1);"
  8829. "}"
  8830. ""
  8831. "void main (void)"
  8832. "{"
  8833. "  const short tam = 100;"
  8834. "  char buf1[tam], buf2[tam], buf3 [tam], buf4[tam];"
  8835. ""
  8836. "  strcpy (buf1, "Ejemplo de la clase ostrstream.");"
  8837. "  strcpy (buf2, "Ejemplo de la clase ostrstream.");"
  8838. "  strcpy (buf3, "Ejemplo de la clase ostrstream.");"
  8839. "  strcpy (buf4, "Ejemplo de la clase ostrstream.");"
  8840. ""
  8841. "  ostrstream s1 (buf1, tam);"
  8842. "  if (! s1)"
  8843. "    error ("s1");"
  8844. ""
  8845. "  ostrstream s2 (buf2, tam, ios::app);"
  8846. "  if (! s2)"
  8847. "    error ("s2");"
  8848. ""
  8849. "  ostrstream s3 (buf3, strlen (buf3) + 2, ios::app);"
  8850. "  if (! s3)"
  8851. "    error ("s3");"
  8852. ""
  8853. "  ostrstream s4 (buf4, tam);"
  8854. "  if (! s4)"
  8855. "    error ("s4");"
  8856. ""
  8857. "  s1 << 'a' << "bc" << ends;"
  8858. "  s2 << 'a' << "bc" << ends;"
  8859. "  // s3 << 'a' << "bc" << ends; // no se añade ni c (de "bc") ni 0 (de ends)"
  8860. "  s4 << 'a' << "bc";"
  8861. ""
  8862. "  cout << buf1 << endl << buf2 << endl << buf4 << endl;"
  8863. "}"
  8864. ""
  8865. "/*"
  8866. "SALIDA:"
  8867. ""
  8868. "«"
  8869. "abc"
  8870. "Ejemplo de la clase ostrstream.abc"
  8871. "abcmplo de la clase ostrstream."
  8872. ""
  8873. "»"
  8874. ""
  8875. "OBSERVACIONES SOBRE EL PROGRAMA:"
  8876. ""
  8877. "1) Con la clase ostrstream se trabaja de una forma similar que con la"
  8878. "clase ofstream, con la diferencia de que ostrstream escribe en un string"
  8879. "y ofstream escribe en un fichero."
  8880. ""
  8881. "2) El modo de operación (tercer parámetro de constructor ostrstream) por"
  8882. "defecto es ios::out."
  8883. "*/"
  8884. ""
  8885. endvis
  8886. beginvis
  8887. no_multiatributo
  8888. cabecera " CLASE strstream "
  8889. borde 2
  8890. coordenadas_completas 1 2 80 24
  8891. color 0 3
  8892. " ▄▄▄▄▄▄▄▄▄▄▄"
  8893. "  strstream    Proporciona entrada y salida simultánea sobre un strstreambuf."
  8894. " ▀▀▀▀▀▀▀▀▀▀▀"
  8895. " ┌───────────────┐"
  8896. " │ strstreambase ├──┐   █▀▀▀▀▀▀▀▀▀▀▀█   ┌───────────┐"
  8897. " ╞═══════════════╡  ├───█ strstream █───┤ <ninguna> │"
  8898. " │ iostream      ├──┘   █▄▄▄▄▄▄▄▄▄▄▄█   └───────────┘"
  8899. " └───────────────┘"
  8900. ""
  8901. "Declarada en: strstrea.h"
  8902. ""
  8903. ""
  8904. " Constructores"
  8905. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8906. "Crea un strstream dinámico:"
  8907. "  strstream ()"
  8908. ""
  8909. "Crea un strstream con un buffer de n bytes especificado:"
  8910. "  strstream (char*, int n, int mode)"
  8911. ""
  8912. "  Si el modo es ios::app o ios::ate, el puntero de lectura/escritura"
  8913. "  es posicionado en el carácter nul del string."
  8914. ""
  8915. ""
  8916. " Funciones miembros"
  8917. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8918. " str"
  8919. ""
  8920. ""
  8921. " Definición"
  8922. " ▀▀▀▀▀▀▀▀▀▀"
  8923. ""
  8924. "class strstream : public strstreambase, public iostream"
  8925. "  {"
  8926. "    public:"
  8927. ""
  8928. "    strstream ();"
  8929. "    strstream (char *, int _sz, int _m);"
  8930. "    ~strstream ();"
  8931. ""
  8932. "    char * str ();"
  8933. "  };"
  8934. ""
  8935. ""
  8936. " Descripción de los métodos"
  8937. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8938. ""
  8939. "▄▄▄▄▄"
  8940. " str    Función miembro"
  8941. "▀▀▀▀▀"
  8942. "┌──────────────┬──────────────────────────────────────────────────────┐"
  8943. "│ ostrstream   │ Devuelve y congela (freeze) el buffer:               │"
  8944. "│ strstream    │   char *str ()                                       │"
  8945. "│              │ Debes liberar el buffer si es dinámico.              │"
  8946. "├──────────────┼──────────────────────────────────────────────────────┤"
  8947. "│ strstreambuf │ Devuelve un puntero al buffer y lo congela (freeze): │"
  8948. "│              │   char *str ()                                       │"
  8949. "└──────────────┴──────────────────────────────────────────────────────┘"
  8950. ""
  8951. ""
  8952. " Programa ejemplo"
  8953. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  8954. ""
  8955. "// Ejemplo sobre la clase strstream."
  8956. ""
  8957. "#include <iostream.h>"
  8958. "#include <strstream.h>"
  8959. ""
  8960. "void main (void)"
  8961. "{"
  8962. "  const short tam = 100;"
  8963. "  char buf[tam];"
  8964. ""
  8965. "  strstream str (buf, tam, ios::in | ios::out);"
  8966. ""
  8967. "  const char sp = ' ';"
  8968. ""
  8969. "  str << 2 << sp << 3.3 << sp << 'x' << sp << "abc";"
  8970. ""
  8971. "  int i;"
  8972. "  float f;"
  8973. "  char c;"
  8974. "  char s[10];"
  8975. ""
  8976. "  str >> i >> f >> c >> s;"
  8977. ""
  8978. "  cout << i << sp << f << sp << c << sp << s << endl;"
  8979. "}"
  8980. ""
  8981. "/*"
  8982. "SALIDA:"
  8983. ""
  8984. "«"
  8985. "2 3.3 x abc"
  8986. ""
  8987. "»"
  8988. ""
  8989. "OBSERVACIONES SOBRE EL PROGRAMA:"
  8990. ""
  8991. "1) Con la clase strstream se trabaja de una forma similar que con la clase"
  8992. "fstream, con la diferencia de que en strstream trabaja con un string y"
  8993. "fstream trabaja con un fichero."
  8994. ""
  8995. "3) Con el modelo de operación (ios::in | ios::out) podemos escribir y leer"
  8996. "simultáneamente sobre un mismo buffer."
  8997. "*/"
  8998. ""
  8999. endvis
  9000. beginvis
  9001. no_multiatributo
  9002. cabecera " FICHERO strstream.h "
  9003. borde 2
  9004. coordenadas_completas 1 2 80 24
  9005. color 0 3
  9006. " ▄▄▄▄▄▄▄▄▄▄▄▄"
  9007. "  STRSTREA.H"
  9008. " ▀▀▀▀▀▀▀▀▀▀▀▀"
  9009. "Declara las clases de flujos de C++ para trabajar con arrays de bytes en"
  9010. "memoria."
  9011. ""
  9012. " Incluye"
  9013. " ▀▀▀▀▀▀▀"
  9014. " iostream.h"
  9015. ""
  9016. " Clases"
  9017. " ▀▀▀▀▀▀"
  9018. " istrstream      ostrstream      strstream       strstreambase"
  9019. " strstreambuf"
  9020. ""
  9021. " Constantes, tipos de datos, y variables globales"
  9022. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9023. " _STRSTREAM_H_"
  9024. ""
  9025. ""
  9026. " Contenido (abreviado):"
  9027. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9028. ""
  9029. "#ifndef __STRSTREAM_H"
  9030. "#define __STRSTREAM_H"
  9031. ""
  9032. "#if !defined( __IOSTREAM_H )"
  9033. "#include <iostream.h>"
  9034. "#endif"
  9035. ""
  9036. "class strstreambuf : public streambuf"
  9037. "  {"
  9038. "    // ..."
  9039. "  };"
  9040. ""
  9041. "class strstreambase : public virtual ios"
  9042. "  {"
  9043. "    // ..."
  9044. "  };"
  9045. ""
  9046. "class istrstream : public strstreambase, public istream"
  9047. "  {"
  9048. "    // ..."
  9049. "  };"
  9050. ""
  9051. "class ostrstream : public strstreambase, public ostream"
  9052. "  {"
  9053. "    // ..."
  9054. "  };"
  9055. ""
  9056. "class strstream : public strstreambase, public iostream"
  9057. "  {"
  9058. "    // ..."
  9059. "  };"
  9060. ""
  9061. "#endif"
  9062. ""
  9063. ""
  9064. " Programa ejemplo"
  9065. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9066. ""
  9067. "// Ejemplo sobre las clases declaradas en el fichero strstream.h."
  9068. ""
  9069. "#include <iostream.h>  // para flujo cout"
  9070. "#include <strstream.h> // para clases istrstream y ostrstream"
  9071. ""
  9072. "void main (void)"
  9073. "{"
  9074. "  char *buffer_fuente = "Ejemplo de las clases istrstream y ostrstream.";"
  9075. "  const int tam = 100;"
  9076. "  char buffer_destino[tam];"
  9077. ""
  9078. "  istrstream flujo_fuente (buffer_fuente);"
  9079. "  ostrstream flujo_destino (buffer_destino, tam);"
  9080. ""
  9081. "  char ch;"
  9082. "  while (flujo_destino && flujo_fuente.get (ch))"
  9083. "    flujo_destino.put (ch);"
  9084. "  flujo_destino << ends;"
  9085. ""
  9086. "  cout << buffer_destino;"
  9087. "}"
  9088. ""
  9089. "/*"
  9090. "SALIDA:"
  9091. ""
  9092. "«"
  9093. "Ejemplo de las clases istrstream y ostrstream."
  9094. "»"
  9095. ""
  9096. "OBSERVACIONES SOBRE EL PROGRAMA:"
  9097. ""
  9098. "1) Tal y como está el programa, el bucle while termina por la segunda"
  9099. "condición: flujo_fuente.get (ch). Si tam fuera 10 en vez de 100, entonces"
  9100. "el bucle while se saldría por la primera condición: flujo_destino. En"
  9101. "este segundo caso, sólo se copiarán 10 caracteres de buffer_fuente, pero"
  9102. "hay que tener en cuenta que en este caso no se guarda el carácter 0 (con"
  9103. "ends) en buffer_destino pues no cabría; esto significa que buffer_destino"
  9104. "no sería un string terminado con el carácter nulo."
  9105. "*/"
  9106. ""
  9107. endvis
  9108. beginv
  9109. centrar_coordenadas
  9110. color 11 3
  9111. borde 2
  9112. cabecera " CLASE bcd Y CLASE complex "
  9113. ""
  9114. "  Además de todos los ficheros de cabecera que acabamos de ver,"
  9115. "  el C++ actual posee dos más: ~bcd.h~ y ~complex.h~. En el primero"
  9116. "  está declarada la clase ~bcd~ para que podamos trabajar con nú-"
  9117. "  meros bcd (binary-code decimal) y en el segundo está declara-"
  9118. "  da la clase ~complex~ para que podamos trabajar con números com-"
  9119. "  plejos."
  9120. ""
  9121. "  Aunque estas dos clases no tienen mucho que ver con la entra-"
  9122. "  da y la salida, que es el objeto de esta lección, las vamos a"
  9123. "  incluir en este lugar puesto que en esta lección es el único"
  9124. "  lugar en el que hemos visto los ficheros de cabecera específi-"
  9125. "  cos al C++, es decir, que no los posee el C ni pueden utilizar-  "
  9126. "  se en un programa de C."
  9127. ""
  9128. endv
  9129. borrar_pantalla
  9130. beginvis
  9131. no_multiatributo
  9132. cabecera " FICHERO bcd.h "
  9133. borde 2
  9134. coordenadas_completas 1 2 80 24
  9135. color 0 3
  9136. " ▄▄▄▄▄▄▄"
  9137. "  BCD.H"
  9138. " ▀▀▀▀▀▀▀"
  9139. "Declara la clase bcd de C++, más los operadores sobrecargados para la clase"
  9140. "bcd y las funciones matemáticas bcd."
  9141. ""
  9142. ""
  9143. " Funciones"
  9144. " ▀▀▀▀▀▀▀▀▀"
  9145. " abs     acos    asin    atan    cos     cosh    exp     log     log10"
  9146. " pow     pow10   real    sin     sinh    sqrt    tan     tanh"
  9147. ""
  9148. ""
  9149. " Constantes, tipos de datos, y variables globales"
  9150. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9151. " _BCD_H"
  9152. " _BcdMaxDecimals"
  9153. " bcdexpo (enum)"
  9154. ""
  9155. ""
  9156. " Constructores"
  9157. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9158. ""
  9159. " ▄▄▄▄▄"
  9160. " ▌bcd▐   Convierte número a decimal en código binario (bcd)."
  9161. " ▀▀▀▀▀"
  9162. " Sintaxis:"
  9163. "   bcd bcd (int x);"
  9164. "   bcd bcd (double x);"
  9165. "   bcd bcd (double x, int decimales);"
  9166. ""
  9167. "Devuelve el equivalente BCD de un número dado."
  9168. ""
  9169. ""
  9170. " Operadores sobrecargados"
  9171. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9172. "    +         -="
  9173. "    -         *="
  9174. "    *         /="
  9175. "    /         <="
  9176. "    ==        >="
  9177. "    !=        <"
  9178. "    +=        >"
  9179. ""
  9180. ""
  9181. " Definición (abreviada)"
  9182. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9183. "// ..."
  9184. ""
  9185. "#ifndef __BCD_H"
  9186. "#define __BCD_H"
  9187. ""
  9188. "#if !defined( __MATH_H )"
  9189. "#include <math.h>"
  9190. "#endif"
  9191. ""
  9192. "#define _BcdMaxDecimals     5000"
  9193. ""
  9194. "class bcd"
  9195. "  {"
  9196. "    public:"
  9197. ""
  9198. "    // Constructores"
  9199. "    _Cdecl bcd();"
  9200. "    _Cdecl bcd(int x);"
  9201. "    _Cdecl bcd(unsigned int x);"
  9202. "    _Cdecl bcd(long x);"
  9203. "    _Cdecl bcd(unsigned long x);"
  9204. "    _Cdecl bcd(double x, int decimals = _BcdMaxDecimals);"
  9205. "    _Cdecl bcd(long double x, int decimals = _BcdMaxDecimals);"
  9206. ""
  9207. "    // Manipuladores bcd"
  9208. "    friend long double _Cdecl real(bcd&);   // Devuelve la parte real"
  9209. ""
  9210. "    // Funciones matemáticas del ANSI C sobrecargadas"
  9211. "    friend bcd _Cdecl abs(bcd&);"
  9212. "    friend bcd _Cdecl acos(bcd&);"
  9213. "    friend bcd _Cdecl asin(bcd&);"
  9214. "    friend bcd _Cdecl atan(bcd&);"
  9215. "    friend bcd _Cdecl cos(bcd&);"
  9216. "    friend bcd _Cdecl cosh(bcd&);"
  9217. "    friend bcd _Cdecl exp(bcd&);"
  9218. "    friend bcd _Cdecl log(bcd&);"
  9219. "    friend bcd _Cdecl log10(bcd&);"
  9220. "    friend bcd _Cdecl pow(bcd& base, bcd& expon);"
  9221. "    friend bcd _Cdecl sin(bcd&);"
  9222. "    friend bcd _Cdecl sinh(bcd&);"
  9223. "    friend bcd _Cdecl sqrt(bcd&);"
  9224. "    friend bcd _Cdecl tan(bcd&);"
  9225. "    friend bcd _Cdecl tanh(bcd&);"
  9226. ""
  9227. "    // Funciones de operadores binarios"
  9228. "    friend bcd _Cdecl operator+(bcd&, bcd&);"
  9229. "    friend bcd _Cdecl operator+(long double, bcd&);"
  9230. "    friend bcd _Cdecl operator+(bcd&, long double);"
  9231. "    friend bcd _Cdecl operator-(bcd&, bcd&);"
  9232. "    friend bcd _Cdecl operator-(long double, bcd&);"
  9233. "    friend bcd _Cdecl operator-(bcd&, long double);"
  9234. "    friend bcd _Cdecl operator*(bcd&, bcd&);"
  9235. "    friend bcd _Cdecl operator*(bcd&, long double);"
  9236. "    friend bcd _Cdecl operator*(long double, bcd&);"
  9237. "    friend bcd _Cdecl operator/(bcd&, bcd&);"
  9238. "    friend bcd _Cdecl operator/(bcd&, long double);"
  9239. "    friend bcd _Cdecl operator/(long double, bcd&);"
  9240. "    friend int _Cdecl operator==(bcd&, bcd&);"
  9241. "    friend int _Cdecl operator!=(bcd&, bcd&);"
  9242. "    friend int _Cdecl operator>=(bcd&, bcd&);"
  9243. "    friend int _Cdecl operator<=(bcd&, bcd&);"
  9244. "    friend int _Cdecl operator>(bcd&, bcd&);"
  9245. "    friend int _Cdecl operator<(bcd&, bcd&);"
  9246. "    bcd& _Cdecl operator+=(bcd&);"
  9247. "    bcd& _Cdecl operator+=(long double);"
  9248. "    bcd& _Cdecl operator-=(bcd&);"
  9249. "    bcd& _Cdecl operator-=(long double);"
  9250. "    bcd& _Cdecl operator*=(bcd&);"
  9251. "    bcd& _Cdecl operator*=(long double);"
  9252. "    bcd& _Cdecl operator/=(bcd&);"
  9253. "    bcd& _Cdecl operator/=(long double);"
  9254. "    bcd  _Cdecl operator+();"
  9255. "    bcd  _Cdecl operator-();"
  9256. ""
  9257. "   // Implementación"
  9258. "   private:"
  9259. ""
  9260. "   // ..."
  9261. "  };"
  9262. ""
  9263. "// ..."
  9264. ""
  9265. "enum bcdexpo"
  9266. "  {"
  9267. "    ExpoZero,"
  9268. "    ExpoInf,"
  9269. "    ExpoNan,"
  9270. "  };"
  9271. ""
  9272. "// ..."
  9273. ""
  9274. "#endif  // __BCD_H"
  9275. ""
  9276. ""
  9277. " Descripción de los métodos"
  9278. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9279. ""
  9280. "La sintaxis de las funciones matemáticas del ANSI C aplicadas a objetos"
  9281. "de la clase bcd es similar así que no se van a describir aquí pues ya se"
  9282. "explicaron en el tutor de C; lo única diferencia está en que donde aparece"
  9283. "el tipo double en la función correspondiente al ANSI C, aparace el tipo"
  9284. "bcd en la correspondiente función matemática sobrecargada; por ejemplo,"
  9285. "el prototipo del ANSI C"
  9286. "  double cos (double x);"
  9287. "se convierte en la función cos sobrecargada correspondiente a números"
  9288. "complejos en"
  9289. "  bcd cos (bcd z);"
  9290. ""
  9291. "Con los operadores sobrecargados para los objetos complejos ocurre lo"
  9292. "mismo que las funciones matemáticas sobrecargadas para los objetos"
  9293. "complejos."
  9294. ""
  9295. "Hay una función (método) nueva en la clase bcd que no tiene correspondencia"
  9296. "con el tipo double:"
  9297. ""
  9298. " ▄▄▄▄▄▄"
  9299. " ▌real▐   Devuelve la parte real del número bcd."
  9300. " ▀▀▀▀▀▀"
  9301. " Sintaxis:"
  9302. "   bcd real (bcd x);"
  9303. ""
  9304. ""
  9305. " Programa ejemplo"
  9306. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9307. ""
  9308. "// Ejemplo de la clase bcd."
  9309. ""
  9310. "#include <iostream.h>"
  9311. "#include <bcd.h>"
  9312. ""
  9313. "void main (void)"
  9314. "{"
  9315. "  bcd b1 (2), b2 (3.3);"
  9316. ""
  9317. "  cout << "b1: " << b1                       // imprime: «b1: 2»"
  9318. "       << endl"
  9319. "       << "b2: " << b2                       // imprime: «b3: 3.3»"
  9320. "       << endl"
  9321. "       << "b1 + b2: " << b1 + b2             // imprime: «b1 + b2: 5.3»"
  9322. "       << endl"
  9323. "       << "abs (b1 - b2): " << abs (b1 - b2) // imprime: «abs (b1 - b2): 1.3»"
  9324. "       << endl"
  9325. "       << "(b1 = b2 - 1): " << (b1 = b2 - 1) // imprime: «(b1 = b2 - 1): 2.3»"
  9326. "       << endl"
  9327. "       << "real (b2): " << real (b2)         // imprime: «real (b2): 3.3»"
  9328. "       << endl;"
  9329. "}"
  9330. ""
  9331. endvis
  9332. beginvis
  9333. no_multiatributo
  9334. cabecera " FICHERO complex.h "
  9335. borde 2
  9336. coordenadas_completas 1 2 80 24
  9337. color 0 3
  9338. " ▄▄▄▄▄▄▄▄▄▄▄"
  9339. "  COMPLEX.H"
  9340. " ▀▀▀▀▀▀▀▀▀▀▀"
  9341. "Declara las funciones matemáticas complejas de C++."
  9342. ""
  9343. ""
  9344. " Incluye"
  9345. " ▀▀▀▀▀▀▀"
  9346. " iostream.h   math.h"
  9347. ""
  9348. ""
  9349. " Funciones"
  9350. " ▀▀▀▀▀▀▀▀▀"
  9351. " abs     acos    arg     asin    atan    conj    cos     cosh    exp"
  9352. " imag    log     log10   norm    polar   pow     pow10   real    sin"
  9353. " sinh    sqrt    tan     tanh"
  9354. ""
  9355. ""
  9356. " Constantes, tipos de datos, y variables globales"
  9357. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9358. " _COMPLEX_H"
  9359. ""
  9360. ""
  9361. " Constructores"
  9362. " ▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9363. ""
  9364. " ▄▄▄▄▄▄▄▄▄"
  9365. " ▌complex▐   Crea números complejos."
  9366. " ▀▀▀▀▀▀▀▀▀"
  9367. " Sintaxis:"
  9368. "   complex complex (double real, double imag = 0);"
  9369. ""
  9370. "Devuelve el número complejo con las partes real e imaginaria dadas."
  9371. ""
  9372. ""
  9373. " Operadores sobrecargados"
  9374. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9375. "    +        +="
  9376. "    -        -="
  9377. "    *        *="
  9378. "    /        /="
  9379. "    ==       !="
  9380. "    <<       >>"
  9381. ""
  9382. ""
  9383. " Definición (abreviada)"
  9384. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9385. "// ..."
  9386. ""
  9387. "#if !defined( __COMPLEX_H )"
  9388. "#define _COMPLEX_H"
  9389. ""
  9390. "#if !defined( __MATH_H )"
  9391. "#include <math.h>"
  9392. "#endif"
  9393. ""
  9394. "class complex"
  9395. "  {"
  9396. "    public:"
  9397. ""
  9398. "    // Constructores"
  9399. "    complex(double __re_val, double __im_val=0);"
  9400. "    complex();"
  9401. ""
  9402. "    // Manipuladores de complex"
  9403. "    friend double _Cdecl real(complex&);   // la parte real"
  9404. "    friend double _Cdecl imag(complex&);   // la parte imaginaria"
  9405. "    friend complex _Cdecl conj(complex&);  // el complejo conjugado"
  9406. "    friend double _Cdecl norm(complex&);   // el cuadrado de la magnitud"
  9407. "    friend double _Cdecl arg(complex&);    // el ángulo en el plano"
  9408. ""
  9409. "    // Crea coordenadas polares de un objeto complex dado"
  9410. "    friend complex _Cdecl polar(double __mag, double __angle=0);"
  9411. ""
  9412. "    // Funciones matemáticas del ANSI C sobrecargadas"
  9413. "    friend double  _Cdecl abs(complex&);"
  9414. "    friend complex _Cdecl acos(complex&);"
  9415. "    friend complex _Cdecl asin(complex&);"
  9416. "    friend complex _Cdecl atan(complex&);"
  9417. "    friend complex _Cdecl cos(complex&);"
  9418. "    friend complex _Cdecl cosh(complex&);"
  9419. "    friend complex _Cdecl exp(complex&);"
  9420. "    friend complex _Cdecl log(complex&);"
  9421. "    friend complex _Cdecl log10(complex&);"
  9422. "    friend complex _Cdecl pow(complex& __base, double __expon);"
  9423. "    friend complex _Cdecl pow(double __base, complex& __expon);"
  9424. "    friend complex _Cdecl pow(complex& __base, complex& __expon);"
  9425. "    friend complex _Cdecl sin(complex&);"
  9426. "    friend complex _Cdecl sinh(complex&);"
  9427. "    friend complex _Cdecl sqrt(complex&);"
  9428. "    friend complex _Cdecl tan(complex&);"
  9429. "    friend complex _Cdecl tanh(complex&);"
  9430. ""
  9431. "    // Funciones de operadores binarios"
  9432. "    friend complex _Cdecl operator+(complex&, complex&);"
  9433. "    friend complex _Cdecl operator+(double, complex&);"
  9434. "        friend complex _Cdecl operator+(complex&, double);"
  9435. "    friend complex _Cdecl operator-(complex&, complex&);"
  9436. "    friend complex _Cdecl operator-(double, complex&);"
  9437. "        friend complex _Cdecl operator-(complex&, double);"
  9438. "    friend complex _Cdecl operator*(complex&, complex&);"
  9439. "        friend complex _Cdecl operator*(complex&, double);"
  9440. "    friend complex _Cdecl operator*(double, complex&);"
  9441. "    friend complex _Cdecl operator/(complex&, complex&);"
  9442. "        friend complex _Cdecl operator/(complex&, double);"
  9443. "    friend complex _Cdecl operator/(double, complex&);"
  9444. "    friend int _Cdecl operator==(complex&, complex&);"
  9445. "    friend int _Cdecl operator!=(complex&, complex&);"
  9446. "    complex& _Cdecl operator+=(complex&);"
  9447. "    complex& _Cdecl operator+=(double);"
  9448. "    complex& _Cdecl operator-=(complex&);"
  9449. "    complex& _Cdecl operator-=(double);"
  9450. "    complex& _Cdecl operator*=(complex&);"
  9451. "    complex& _Cdecl operator*=(double);"
  9452. "    complex& _Cdecl operator/=(complex&);"
  9453. "    complex& _Cdecl operator/=(double);"
  9454. "    complex _Cdecl operator+();"
  9455. "    complex _Cdecl operator-();"
  9456. ""
  9457. "    // Implementación"
  9458. "    private:"
  9459. ""
  9460. "    double re, im;"
  9461. "  };"
  9462. ""
  9463. ""
  9464. "// Funciones inline de complex"
  9465. ""
  9466. "// ..."
  9467. ""
  9468. "#endif  // __COMPLEX_H"
  9469. ""
  9470. ""
  9471. " Descripción de los métodos"
  9472. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9473. ""
  9474. "La sintaxis de las funciones matemáticas del ANSI C aplicadas a objetos"
  9475. "de la clase compleja es similar así que no se van a describir aquí pues"
  9476. "ya se explicaron en el tutor de C; lo única diferencia está en que donde"
  9477. "aparece double en la función correspondiente al ANSI C, aparace el tipo"
  9478. "complex en la correspondiente función matemática sobrecargada; por ejemplo,"
  9479. "el prototipo del ANSI C"
  9480. "  double cos (double x);"
  9481. "se convierte en la función cos sobrecargada correspondiente a números"
  9482. "complejos en"
  9483. "  complex cos (complex z);"
  9484. ""
  9485. "Con los operadores sobrecargados para los objetos complejos ocurre lo"
  9486. "mismo que las funciones matemáticas sobrecargadas para los objetos"
  9487. "complejos."
  9488. ""
  9489. "Sí merece la pena explicar las nuevas funciones (métodos) aportados por"
  9490. "la clase complex: real(), imag(), conj(), norm(), arg() y polar():"
  9491. ""
  9492. " ▄▄▄▄▄▄"
  9493. " ▌real▐   Devuelve la parte real de un número complejo."
  9494. " ▀▀▀▀▀▀"
  9495. " Sintaxis:"
  9496. "   double real (complex x);"
  9497. ""
  9498. " ▄▄▄▄▄▄"
  9499. " ▌imag▐   Devuelve la parte imaginaria de un número complejo."
  9500. " ▀▀▀▀▀▀"
  9501. " Sintaxis:"
  9502. "   double imag (complex x);"
  9503. ""
  9504. "Los datos asociados a un número complejo están compuestos por dos números"
  9505. "en coma flotante (double). La función imag() devuelve el que se considera"
  9506. "parte imaginaria de los dos."
  9507. ""
  9508. " ▄▄▄▄▄▄"
  9509. " ▌conj▐   Devuelve el complejo conjugado de un número complejo."
  9510. " ▀▀▀▀▀▀"
  9511. " Sintaxis:"
  9512. "   complex conj (complex z);"
  9513. ""
  9514. "Devuelve el complejo conjugado del número complejo z."
  9515. ""
  9516. " ▄▄▄▄▄▄"
  9517. " ▌norm▐   Devuelve el cuadrado del valor absoluto."
  9518. " ▀▀▀▀▀▀"
  9519. " Sintaxis:"
  9520. "   double norm (complex x);"
  9521. ""
  9522. "La norma puede desbordarse por encima (overflow) si la parte real o la"
  9523. "parte imaginaria son suficientemente grandes."
  9524. ""
  9525. " ▄▄▄▄▄"
  9526. " ▌arg▐   Da el ángulo de un número en el plano complejo."
  9527. " ▀▀▀▀▀"
  9528. " Sintaxis:"
  9529. "   double arg (complex z);"
  9530. ""
  9531. "El eje real positivo tiene ángulo 0, y el eje imaginario positivo tiene"
  9532. "ángulo pi/2. Si z es 0, devuelve 0."
  9533. ""
  9534. " ▄▄▄▄▄▄▄"
  9535. " ▌polar▐   Calcula el número complejo con la magnitud y el ángulo dados."
  9536. " ▀▀▀▀▀▀▀"
  9537. " Sintaxis:"
  9538. "   complex polar (double mag, double angulo);"
  9539. ""
  9540. "El ángulo por defecto es 0. Estas dos declaraciones son iguales:"
  9541. ""
  9542. "  polar (mag, angulo);"
  9543. ""
  9544. "  complex (mag * cos (angulo), mag * sin (angulo));"
  9545. ""
  9546. ""
  9547. " Programa ejemplo"
  9548. " ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
  9549. ""
  9550. "// Ejemplo de la clase complex."
  9551. ""
  9552. "#include <iostream.h>"
  9553. "#include <complex.h>"
  9554. ""
  9555. "void main (void)"
  9556. "{"
  9557. "  complex z1 (2.2), z2 (3, 4);"
  9558. ""
  9559. "  cout << "z1: " << z1;                   // imprime: «z1: (2.2, 0)»"
  9560. "  cout << endl;"
  9561. "  cout << "z2: " << z2;                   // imprime: «z2: (3, 4)»"
  9562. "  cout << endl;"
  9563. "  cout << "z1 + z2: " << z1 + z2;         // imprime: «z1 + z2: (5.2, 4)»"
  9564. "  cout << endl;"
  9565. "  cout << "abs (z1-z2): " << abs (z1-z2); // imprime: «abs (z1-z2): 4.079216»"
  9566. "  cout << endl;"
  9567. "  cout << "(z1 = z2-1): " << (z1 = z2-1); // imprime: «(z1 = z2-1): (2, 4)»"
  9568. "  cout << endl;"
  9569. "  cout << "real (z2): " << real (z2);     // imprime: «real (z2): 3»"
  9570. "  cout << endl;"
  9571. "  cout << "imag (z2): " << imag (z2);     // imprime: «imag (z2): 4»"
  9572. "  cout << endl;"
  9573. "  cout << "conj (z1): " << conj (z1);     // imprime: «conj (z1): (2, -4)»"
  9574. "  cout << endl;"
  9575. "}"
  9576. ""
  9577. endvis
  9578. beginv
  9579. color 15 7
  9580. centrar_coordenadas
  9581. "~                                                           ~"
  9582. "~    f f f f    i i i i    n     n    a a a a    l          ~"
  9583. "~    f             i       n n   n    a     a    l          ~"
  9584. "~    f f f         i       n  n  n    a a a a    l          ~"
  9585. "~    f             i       n   n n    a     a    l          ~"
  9586. "~    f          i i i i    n     n    a     a    l l l l    ~"
  9587. "~                                                           ~"
  9588. "~                                                           ~"
  9589. "~   D E    L A    T E O R I A    D E L    L E N G U A J E   ~"
  9590. "~                                                           ~"
  9591. "~              ~              ~                               ~"
  9592. "~              ~   ████████                      ~            ~"
  9593. "~              ~   ██            ██       ██     ~            ~"
  9594. "~              ~   ██          ██████   ██████   ~            ~"
  9595. "~              ~   ██            ██       ██     ~            ~"
  9596. "~              ~   ████████                      ~            ~"
  9597. "~              ~              ~                               ~"
  9598. "~                                                           ~"
  9599. endv
  9600. end lección 8
  9601.